データベースのプログラムで用語のvid列を変更することはできますか?


8

翻訳、エイリアス、ノード参照などのすべてのデータを保持することで、用語をある用語から別の用語に移動する必要があります。

vidデータベースで列の値を直接変更することはできますか?用語には、処理する必要がある階層関係がありません。

回答:


11

データベース

Drupalを通じて、または外部からSQLクエリを実行するだけで、Drupalで多くのことを実行できます。一般に、このアプローチを採用することは決してありません。うまく動作する場合もありますが、ほとんどの場合、このようにする理由はありません。

API

Drupalには豊富なAPIがあり、これは常にDrupalの重要な機能であるDrupal 6、7、8に当てはまります。実際の例では、を使用taxonomy_term_loadtaxonomy_term_saveて用語の更新を容易にすることができます。これにより、を含むすべてのデータパーツを編集できますvid。APIで禁止されいることを行っているからといって、自動的に機能するだけではなく、うまくいく可能性が大幅に向上します。

この具体的な例では、APIは必ずしも必要なことを何もしません。これは、用語にいくつかの内部データを設定し、フック文字モジュールを呼び出して、更新されたことを認識します。

変更したい用語が階層の一部である場合、状況が崩れる可能性があることに注意してください。フィールドが新しいボキャブラリで用語を参照することが許可されていない場合、用語がノードを参照することで問題が発生する可能性もあります。

マイグレーション

データの移行は防弾ソリューションであり、巨大なデータセットがない限り、非常に簡単に開発および実行できます。新しい用語を作成し、移行するコンテンツを移行してから、古い用語を削除するという考え方です。更新フックとして、サンプルコードは次のようになります。

/**
 * Put in modules .install file, replace xxxx with 7000 or higher
 */
function MODULE_NAME_update_XXXX(&$sandbox) {
  $term = taxonomy_term_load(CONSTANT_WITH_TID);
  $new_term = clone $term;
  unset($new_term->tid);
  unset($new_term->tid);
  $new_term->vid = CONSTANT_WITH_VID;
  taxonomy_term_save($term);
  // Find all nodes we want to update and update them.
  // If there is a lot of nodes, can use $sandbox to make this a batch job.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
  $result = $query->execute();
  foreach (node_load_multiple(array_keys($result['node'])) as $node) {
    $node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
    node_save($node);
  }
  // Migration all done - delete the old term.
  taxonomy_term_delete($term->tid);
}

上記のコードは純粋にサンプルコードであり、暗記されていることに注意してください。構文エラーまたはその他のエラーが発生する可能性があり、多くの仮定を行います。これは単にアイデアを説明し、移行は大したことではないかもしれないことを示すためです。


4

Drupalを使用する場合、データベースを直接変更することはお勧めできません。私たちが知っていれば、すべてのことが影響し、それに応じて必要な変更を行うことができますどこでもはい、OKデータベースで直接変更を行うこと。この場合、これはUIからは実行できないためです。注:用語に関連付けられているノードがある場合は、手動でそれを処理する必要があります。

Drupal 7で用語語彙を変更する方法を説明しているこのリンクを確認してください。データベースを使用して、Drupal 7で分類用語の語彙を変更します


私がこれで見ている唯一の問題は-ある場合、いくつかの値を持つ用語に添付されたフィールドがあり、そのvidを変更すると、フィールドに格納されているデータが失われます。
Ashish Deynap

はい、そのため、ノードも接続されている場合は、それらも処理する必要があることも述べました
Yogesh

しかし、どんなデータもvidによって用語に添付されていますか?TIDキーだけでなく
Molfar

いいえ、用語に添付されているデータはすべてtidに関連しています。vidは語彙IDのみを参照するために使用され、それ以外は参照されません。
Yogesh

4

質問でそれを説明した方法でその用語を変更することはお勧めしません。代わりに、別のアプローチを使用して(指定された順序で)同様の結果を達成します。

手順1-今後のノードの更新で新しい用語の使用を開始する

「今後」ノードの更新(または作成される新しいノード)がその新しいフィールドを使用するように、新しい分類用語フィールドを作成します。これらの用語はノードに使用されていると思います(ユーザーなどの他のエンティティタイプに使用する場合)。これらのエンティティにも同じアプローチを使用できます。

使用規則そうのようなルールを作成するには、モジュールを:

  • ルールイベント:before saving content
  • ルール条件:
    • entity has field、フィールド=古いフィールド。
    • AND NOT(entity has field、フィールド=新しいフィールド)。
  • ルールアクション:set Drupal message、これには、古いフィールドを空白にする必要があるという指示が含まれており、新しいフィールドには適切な値が含まれている必要があります。

ステップ2-ルールを使用してプロセスを高速化する

明らかに、ステップ1のアプローチは、これを手動で、一度に1ノードずつ行う必要がある場合、「ある程度」時間がかかります。しかし、ビュー(更新する同様のノードのリストを作成するため)とVBO(このようなリストを一括更新するため)を使用すると、このプロセスをかなり高速化できるはずです(すべきです)。

特にあなたが使用したい場合はルールを、このようなVBOビュー用のカスタム一括操作を作成するには、などの答えで説明した「VBOビュー用のカスタム一括操作を作成するためにルールを使用する方法は?」。このようなカスタムバルク操作(ルールエクスポート形式)の実装に役立つルールコンポーネントのプロトタイプを次に示します。

{ "rules_replace_a_term_field_by_another_term_field" : {
    "LABEL" : "Replace a term field by another term field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
      { "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
      { "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
    ]
  }
}

上記のプロトタイプを説明するいくつかの詳細:

  • ノードをパラメーターとして使用します。
  • これらはルール条件です:

    • エンティティ(=ノード)にフィールドがあるかどうかを確認しますfield_sample_tags
    • エンティティ(=ノード)にフィールドがあるかどうかを確認しますfield_demo_tags
    • フィールドの値が、field_demo_tags置き換えたい用語に対応しているかどうかを確認します(この例では、用語にはid =があります1)。この条件が満たされない場合、ルールアクションは実行されないことに注意してください。
  • ルールアクションは次のとおりです。

    • fieldのfield_sample_tags値を、term id = 31(置き換えられるボキャブラリーの用語と一致する、新しく作成されたボキャブラリーの用語)の用語と等しくなるように設定します。
    • 以下のようなサイトにメッセージを表示するTerm updated in node with id = 72のに対し、72更新されたノードのノードIDです。

必要に応じて、上記のプロトタイプのフィールド名のマシン名と使用されている用語IDを適合させます。次に、(ルールUIを使用して)自分のサイトにインポートし、インポートしたルールコンポーネントの右側にある「実行」リンクを使用してQAテストします(そして、「直接入力」に切り替えた後、ノードIDを入力してテストしますモード」でノードIDを指定できるようにします)。テスト中にこのようなTerm updated in node ...メッセージが表示されない場合は、選択したノードがルールの条件で指定された用語の値を使用していないことが原因であると考えられます。

ステップ3-VBOを最後の仕上げとして使用する

手順2のこのルールコンポーネントのQAテストが完了したら、処理するノードのVBOビューを作成します。ここでは、上記のルールプロトタイプ(またはニーズに合わせてそのバリエーション)を参照します。

このアプローチの利点

このアプローチを使用すると、カスタムデータベースを一切使用せずに(データベースを直接更新する場合と比較して)データの不整合を招くリスクを最小限に抑えることができます(ビューUIとルールUIのみを使用します)。


ビュー、VBO、ルールがすでにインストールされていると想定します。それ以外の場合は、このソリューションの3つのモジュールをインストールする必要があります。さらに、実装する必要がある構成「コード」は、更新フックで実行する必要があるものよりも複雑ではありません。私のポイントは、ルールとビューの使用は、あなたがそれを健全にするほど単純ではないということです。また、ビューとルールを使用してほとんど何でも作成できる一方で、そうすることが常に良いアイデアであるとは限らないことも覚えておく価値があります。
googletorp

1
はい、確かに:ビュー、ルール、またはVBOを使用するには、モジュールをインストールする必要があります(+有効)。しかし、約9万9千のD7サイトから、約8万1 千のサイトもあり、ビューもあり、80%を超えています。また、ルールやVBOを使用する理由がないサイトの場合:これらのモジュールは、そのような変換を行うためにのみ必要です(完了したら、必要に応じて削除できます)。シンプルさについて:IMOはむしろ経験の問題です。このアプローチの利点は、サイト構築のスキルしか必要としないことです(経験豊富なPHP開発者が利用できない/手頃な価格ではない可能性があります)。
Pierre.Vriens

2

私はあなたがプログラムで言っていることを知っていますが、モジュールを使用したい場合は、Taxonomy Managerを使用できます

このモジュールは、分類法を管理するための強力なインターフェースを提供します。語彙は動的ツリービューに表示され、親用語を展開してネストされた子用語をリストしたり、折りたたんだりできます。

分類法マネージャーには、次の操作と主な機能があります。

  • 動的ツリービュー
  • 一括削除
  • 新しい用語の大量追加
  • 階層内の用語の移動用語のマージ(7.xの用語マージモジュールを使用)
  • 上矢印と下矢印を使用した高速の重量変更(およびAJAXの節約)
  • AJAXを利用した用語編集フォーム
  • シンプルな検索インターフェース
  • 用語のCSVエクスポート
  • 多言語語彙のi18nサポート(言語ごと)
  • 階層内の用語の移動、新しい翻訳の追加、異なる語彙間の用語の切り替えのためのダブルツリーインターフェイス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.