Migrate Module Caveats. May Save You Some Time... and Hair

While working with Migrate and Migrate 2.6 beta 1 I stumbled upon several undocumented "surprises" which are hopefully going to be documented, but so far, you can spend lots of time trying to figure out what may be wrong. Here's roundup of my findings:

1. There is one correct way of registering migrations and handlers

You should do this in hook_migrate_info(), your register code may look like this:

/**
 * You must implement hook_migrate_api(), setting the API level to 2, for
 * your migration classes to be recognized by the Migrate module.
 */
function MY_MODULE_migrate_api() {
  $api = array(
    'api' => 2,
 
    // Custom field handlers.
    'field handlers' => array(
      'ExampleMigrateFieldHandler',
    ),
 
   // Groups.
   'groups' => array(
     'nodes' => array('title' => t('Nodes')),
   ),
 
    // Migration classes.
    'migrations' => array(
      'ExampleNode' => array(
        'class_name' => ExampleNodeMigration',
        'group_name' => 'nodes',
      ),
    ),
  );
 
  return $api;
}

2. Current version of product reference field handler doesn't support multiple values

You heard it right! If you have more than one product reference per field, migration will fail. There is a patch already, however it is not even in dev version of commerce_migrate. But wait no longer, just disable original MigrateCommerceProductReferenceFieldHandler and register your own handler which should look like this:

class CustomMigrateCommerceProductReferenceFieldHandler extends MigrateFieldHandler {
  public function __construct() {
    $this->registerTypes(array('commerce_product_reference'));
  }
  public function prepare($entity, array $field_info, array $instance, array $values) {
    $migration = Migration::currentMigration();
    $arguments = (isset($values['arguments']))? $values['arguments']: array();
    $language = $this->getFieldLanguage($entity, $field_info, $arguments);
    // Setup the standard Field API array for saving.
    $delta = 0;
    if(!is_array(reset($values))) {
      $values = array($values);
    }
    foreach (array_filter($values) as $value) {
      $return[$language][$delta]['product_id'] = reset($value);
      $delta++;
    }
    if (!isset($return)) {
      $return = NULL;
    }
    return $return;
  }
}

Posted this snippet on dropbucket.org: http://dropbucket.org/node/629.

This is a patched version of the original MigrateCommerceProductReferenceFieldHandler which now supports multi-values.

3. Current version of date_migrate.module doesn't support new way of field_handler registration

Which means that your data fields won't get imported properly if you won't register DateMigrateFieldHandler explicitly. To do this, add it to your hook_migrate_api():

function MY_MODULE_migrate_api() {
  $api = array(
    'api' => 2,
 
    // Date module doesn't register handler according to new Migrate 2.6 requirements
    // that's why we register it here.
    'field handlers' => array(
      'DateMigrateFieldHandler',
    ),
 
    // Our migration classes.
    'migrations' => array(
      'ExampleNode' => array(
        'class_name' => ExampleNodeMigration',
        'group_name' => 'nodes',
      ),
    ),
  );
 
  return $api;
}

4. It is not straightforward how to define migrate destination for commerce_product entity

In your migrate class __construct() function do this:

$this->destination = new MigrateDestinationCommerceProduct('commerce_product', 'YOUR_PRODUCT_BUNDLE_NAME');

Key schema for commerce product is defined as:
MigrateDestinationCommerceProduct::getKeySchema('commerce_product');

5. In migrate 2.6 you can use hash value to track changed source rows

I've already described this in details in my previous post Using Hash Value (track_changes) To Detect Source Data Changes in Migrate for Drupal 7.

Hope these notes will save someone a little bit of precious time.

Comments

Submitted by scott sawyer on Thu, 2013-05-30 14:24

Thank you for this post, I am working on a sizable migration and working through the migration module. There are a lot of blogs and how to articles, but they seem to slab various versions of the module, so I am spending a lot of time piecing the together bits from several sources and a lot of trial and error. Lots of good info in this post.

Add new comment

You are here