Как ссылаться на существующие термины таксономии при миграции


Я пытаюсь перенести узлы с помощью поля ссылки на термин. Условия не перенесены и уже существуют на целевом сайте. В классе миграции есть метод, который, как подтверждено, уже выбрал правильный идентификатор термина на новом сайте.

При запуске миграции появляется ошибка:

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
...
Author: CR47, 2017-01-23

2 answers

Я смог решить проблему, переместив запросы для идентификатора термина в плагин процесса.

/**
 *
 * @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
Author: CR47, 2017-01-24 16:09:10

Я смог просто сделать это с помощью плагина migration_lookup:

 tid:
   plugin: migration_lookup
   migration: categories
   source: id
 0
Author: Berend de Boer, 2018-02-09 00:45:57