web-dev-qa-db-ja.com

移行:prepare()とprepareRow()の違いは何ですか?

Migrateモジュールの使用:prepareRow()が行でフィルターを実行し、いくつかの条件に基づいてTRUEまたはFALSEを返す必要があることを理解しています。

  • いつprepare()を使用するか
  • いつprepareRow()を使用するか
  • 上記のいずれかで削除/含める可能性がある行の結果をフィルタリングするために、最初のSQLクエリにフィルターを追加しない理由

ありがとう!

8
user4984

これはすべて、プロジェクトによって提供される Migrations classes のドキュメントで詳しく説明されています。具体的には Commononly Implemented Migration methods ページに次のように記載されており、さらに簡単な関数の実装例が含まれています。ドキュメントから...

関数prepare_row($ row)

PrepareRow()メソッドは、データ行をロードした後、ソースクラスのnext()メソッドによって呼び出されます。引数$ rowは、ソースによって提供される生データを含むstdClassオブジェクトです。 prepareRow()を実装する主な理由は2つあります。

  1. 他のメソッドやハンドラーを通過する前にデータ行を変更するには、たとえば、関連データのフェッチ、ソースフィールドの分割、ロジックに基づく新しいソースフィールドの結合または作成など。
  2. 行をスキップする(FALSEを返す)。

関数prepare($ entity、stdClass $ row)

Migrationクラスのprepare()メソッドは、すべてのフィールドレベルのprepare()メソッドを呼び出した後、宛先オブジェクトが保存される直前に、宛先クラスのprepare()メソッドによって呼び出されます。 $ entity引数は、初期フィールドマッピングによって入力され、フィールドレベルのメソッドによって操作される宛先オブジェクトです。 $ row引数は、prepareRow()およびすべてのコールバックが適用された後のデータを含むオブジェクトです。 prepare()メソッドは、宛先オブジェクトをDrupalデータベースに保存する前に操作する最後の機会です。フィールドハンドラーの後に呼び出されるため、フィールドは完全に拡張された形式(つまり、Drupal 7では、テキストフィールド値は$entity->field_textual_data['und'][0]['value']だけではなく$entity->field_textual_data)

Migrate モジュールは、ソースデータから宛先の場所と構成への移行プロセスをカプセル化できるフレームワークです。移行は以下で構成されます。

  • データの場所を定義する
  • データの行き先を定義する
  • データ(行)をフェッチする
  • データを無害化する
  • データの移動を開始します(エンティティに移動します)
  • 実際にデータを移動する
  • データを移動した後、追加のアクションを実行します

APIは、移行のこのライフサイクルで移動されるデータに影響を与えるフックを提供します。最初のクエリを介して移行からデータを除外することにより、移動できるデータ全体をどの程度制御できるかを制限します。サブマイグレーションの場合、これが役立つことがあります。ただし、一般的なコンテンツの移行では、移行をできるだけ包括的にする必要があります。

9
tenken

クエリに書き込んで適切な行を選択できる場合は、行を移行する前にいくつかのパラメーターが必要になる可能性があるより複雑なシステムでpreprareRow()を使用できます。このような場合、すべての行を実行し、行ごとにロジックを実行する方が簡単です。

prepare()はprepareRow()の後に実行され、データベースに保存される前にエンティティを変更する最後のチャンスです。

これに関するいくつかの詳細はここにあります: https://www.drupal.org/node/1132582

6
Neograph734

これは部分的な答えであり、完全ではありません。これらの両方についてもっと知りたいと思っています。したがって、これは議論の一部かもしれません。次のコードスニペットと上記のクラスの使用例のため、コメントではなく回答として記述しましたが。

私がprepareRow()を使用しているいくつかの例を示します。

最近、drupal以外のデータベースからインポートするデータをいくつか与えていました。追加するエンティティでは、データインポートにないフィールドを入力する必要があります。

ソースクラスを作成する前に、

  $source_fields = array(
    'changed' => t('Timestamp of when the change was made.'),
    'created' => t('Timestamp of when the node was Created.'),
 );

次に、関数prepareRowで次のことができます

$nowtimestamp = mktime(date('Y-m-d'));
$row->changed = $nowtimestamp;
$row->created = $nowtimestamp;

必要に応じて、php if/elseステートメントをここで実行することもできます。

また、コードでprepare関数を使用し、それを使用してエンティティに値を割り当てています。

$account->field_job_location [und][0]['tid'] = $row->job_location_tid;

このシナリオでは、独自のカスタムノードプラグインを作成したので、これを使用するだけで済みました。

また、それを計算する必要がある場合は、prepare()の前に実行されるprepareRowでそれを行うことができます

たとえば、インポートでは「Town」というラベルの付いた値があり、これを用語IDに変えることができます。

 if ($TownCity == 'London' ){
            $row->job_location_tid = '10';
      } else {
        $row->job_location_tid = '11';
      } 

これがお役に立てば幸いです。

3
Deejay