1

I am using Migrate D2D on a Drupal 6 to Drupal 7 migration right now.

I have three types: type1, type2, type3. Each of the three types has a entityreference field on it, which is configured to be able to point to all three types. This means that there can be circular references, and when a particular node is being migrated, the destination node may not exist yet and could potentially be any of the three types.

My migration class looks like this:

class MyNodeMigration extends DrupalNode6Migration {
  public function __construct(array $arguments) {
    parent::__construct($arguments);

    $this->addFieldMapping('field_legacy_nid', 'nid');

    $this->addFieldMapping('field_the_reference', 'field_the_reference')
      ->sourceMigration(array('type1', 'type2', 'type3');
  }
}

$node_arguments = array(
  array(
    'class_name' => 'MyNodeMigration',
    'description' => 'type1',
    'machine_name' => 'type1',
    'source_type' => 'type1',
    'destination_type' => 'type1',
    'dependencies' => array('roles', 'users'),
  ),

  array(
    'class_name' => 'MyNodeMigration',
    'description' => 'type2',
    'machine_name' => 'type2',
    'source_type' => 'type2',
    'destination_type' => 'type2',
    'dependencies' => array('roles', 'users'),
  ),

  array(
    'class_name' => 'MyNodeMigration',
    'description' => 'type3',
    'machine_name' => 'type3',
    'source_type' => 'type3',
    'destination_type' => 'type3',
    'dependencies' => array('roles', 'users'),
  ),
);

$common_node_arguments = $common_arguments + array(
  'user_migration' => 'users',
);

foreach ($node_arguments as $arguments) {
  $arguments = array_merge_recursive($arguments, $common_node_arguments);

  Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
}

When I run the migrations, most nodes are fine, but I get a decent amount of Stubs (*) created. Some of the destination nodes have the entityreference pointing to these Stub nodes. The source nodes are fine.

What I have uncovered is that the bundle on the destination nodes that are being made as stubs are incorrect, and look like they are all type1. A node of the proper type does end up being created, but it never gets set as the entityreference target.

Another way to explain this is that I end up with

  • node: nid=123, type=type1
  • node: nid=234, type=type1, field_the_reference=123
  • node: nid=345, type=type2

where it should be

  • node: nid=234, type=type1, field_the_reference=345
  • node: nid=345, type=type2

How do I handle this situation?

(*): a "Stub" in the context of this question here refers to a node which is created for the purpose of being a reference target, but does not get its data initially. The term is used throughout the Migrate documentation and source code.

  • What's a "Stub" in the context of this question here? Is it the same as what is explained about a Stub on drupal.org/node/1013506 (the link in your own answer)? – Pierre.Vriens Dec 20 '15 at 9:29
  • @Pierre.Vriens, yes, it refers to a nodes which is created for the purpose of being a reference target, but does not get its data initially. The term is used throughout the Migrate documentation and source code. – mpdonadio Dec 20 '15 at 13:29
  • OK, merci for clarifying. Please verify how I tried to integrate that clarification in your question (with the least possible addition). Feel free of course to rework/rephrase if needed (worst case, if you don't like it all just rollback). After your review, please remove both my comments here (= obsolete). – Pierre.Vriens Dec 20 '15 at 22:36
1

The main problem has to do with how stubs are handled in Migrate, and is related to a known issue.

In short, when the destination can be one of several content types, the migration doesn't know what content type to create the stub as in a generic way.

My current workaround for this is to prevent stubs from being created:

abstract class MyNodeMigration extends DrupalNode6Migration {
  ... 

  protected function createStub(Migration $migration, array $source_id) {
    return FALSE;
  }
}

When the migration runs, stubs don't get created, but the entity reference fields in my destinations also don't get populated.

I then manually reset the highwater mark

db_update('migrate_status')
  ->fields(array('highwater' => 0))
  ->condition(...)
  ->execute();

and then rerun the migrations. Since the destination nodes exists, the entity reference fields can be populated properly.

  • I would absolutely love to have a better solution than this if anyone would like to add an answer. – mpdonadio Jul 18 '14 at 13:52

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.