4

I'm trying to migrate nodes with a term reference field. The terms are not migrated and already exist in the destination site. There is a method in the migration class which is confirmed to already select the correct term ID on the new site.

When the migration is run an error appears:

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)

The migration appears to be trying to get the term data from the migration database instead of the destination (default) database.

migrate plus yml:

...
process:
  field_section: Section
...

migration class:

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();
  }
}

-------------UPDATE-------------

I've also tried using a custom plugin. The same error occurs. Plugin class:

/**
 *
 * @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(),
    ];
  }

}

Updated yml:

...
process:
  field_section:
    plugin: existing_term
    source: Section
...
0

I was able to solve the issue by moving the queries for the term ID to the process plugin.

/**
 *
 * @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(),
    ];
  }

}

It seems like having the queries in the main class were confusing the migration into thinking the term data was in the migration source database.

0

I was able to simply do this with the migration_lookup plugin:

 tid:
   plugin: migration_lookup
   migration: categories
   source: id

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.