web-dev-qa-db-ja.com

移行で既存の分類用語を参照する方法

用語参照フィールドを持つノードを移行しようとしています。用語は移行されず、移行先サイトにすでに存在しています。新しいサイトで正しい用語IDを既に選択していることが確認されている移行クラスにメソッドがあります。

移行を実行すると、エラーが表示されます。

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'migration_db.taxonomy_index' doesn't exist:    [error]
SELECT 1 AS expression
FROM
{taxonomy_index} taxonomy_index
WHERE ( (nid = :db_condition_placeholder_0) AND (tid = :db_condition_placeholder_1) AND (status =
:db_condition_placeholder_2) ); Array
(
    [:db_condition_placeholder_0] => 2290
    [:db_condition_placeholder_1] => 4
    [:db_condition_placeholder_2] => 1
)
 (/home/vagrant/docroot/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php:770)

移行は、移行先(デフォルト)データベースではなく、移行データベースから用語データを取得しようとしているようです。

移行プラスyml:

...
process:
  field_section: Section
...

移行クラス:

class MyNodeMigration extends SqlBase {
  public function query() {
    return $this->select('TableA', 'ta')
      ->fields('ta', ['Id', 'Body', 'OriginalId']);
  }    
 ...
  public function prepareRow(Row $row) {
    $row->setSourceProperty('Section', $this->convertToTermId($row->getSourceProperty('OriginalId'));
  }

  public function convertToTermId($original_id) {
    return $this->getDatabase()->select('TableB', 'tb')
      ->fields('tb', ['DrupalTermId'])
      ->condition('OldId', $original_id)
      ->execute()
      ->fetchField();
  }
}

- - - - - - -更新 - - - - - - -

また、カスタムプラグインを使用してみました。同じエラーが発生します。プラグインクラス:

/**
 *
 * @MigrateProcessPlugin(
 *   id = "existing_term"
 * )
 */
class MigrateProcessExistingTerm extends ProcessPluginBase {
  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $term = Term::load($value);
    return [
      'target_id' => $term->id(),
    ];
  }

}

Ymlの更新:

...
process:
  field_section:
    plugin: existing_term
    source: Section
...
4
CR47

用語IDのクエリをプロセスプラグインに移動することで問題を解決できました。

/**
 *
 * @MigrateProcessPlugin(
 *   id = "existing_term"
 * )
 */
class MigrateProcessExistingTerm extends ProcessPluginBase {
  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {

    db_set_active('my_migration');

    $sub_task_id = db_select('TableA', 'ta')
      ->fields('ta', ['OriginalId'])
      ->condition('Id', $value)
      ->execute()
      ->fetchField();

    $term_id = db_select('TableB', 'tb')
      ->fields('tb', ['DrupalTermId'])
      ->condition('OriginalId', $original_id)
      ->execute()
      ->fetchField();

      db_set_active('default');

    $term = Term::load($term_id);

    return [
      'target_id' => $term->id(),
    ];
  }

}

メインクラスにクエリがあると、移行が混乱し、データという用語が移行ソースデータベースにあると考えるようになりました。

0
CR47

私はmigration_lookupプラグインでこれを簡単に行うことができました:

 tid:
   plugin: migration_lookup
   migration: categories
   source: id
0
Berend de Boer