Migrating Drupal 6 to Drupal 7 with the Migration Framework

We do quite a lot of migrations at work and previously I've seen other developers roll many different solutions from using a Feeds and Services combination to rolling their own importers but it was my turn and I decided to carry out some further research.

Research

During my research I tried quite a few other modules which offered basic export/import like functionality but other than Node Export I really didn't have much success getting any of them to work. I eventually came across the Drupal Migrate Framework and some Drupal to Drupal specific migration classes.

Migrate and Migrate D2D

The Migrate and Migrate D2D modules are a framework for developers to implement custom migrations. The migrate module provides basic migrate functionality while the migrate_d2d module extends on that functionality providing interfaces for reading and importing into Drupal 5, 6 and 7. Migrate comes with Drush integration and supports rolling back migrations which is very handy during development.

Go ahead and install the migrate and migrate_d2d modules on your Drupal 7 instance and then create yourself a module to assist with the migration. The below examples use the module name: devblog_migrate

Let's Look at Some Code

Connecting to the Drupal 6 Instance

You should put the following code into your settings.php file or you can specify database connection details within your migration scripts if you prefer.

  array (
    'default' =>
    array (
      'database' => 'db_drupal7',
      'username' => 'drupal7_user',
      'password' => '',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
  // Here we add in the connection to our D6 database.
  'legacy' =>;
  array (
    'default' =>;
    array (
      'database' => 'db_drupal6',
      'username' => 'drupal6_user',
      'password' => '',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);

A bit of boilerplate code to setup the Migration module.

 2,
  );

  return $api;
}

Making Migrate Aware

We need to give the migrate module a point when it looks for any new migrations. We do this when the Drupal cache is flushed.

 'legacy',
    'source_version' => 6,
  );

  // Register migrations.
  _devblog_migrate_article($common_arguments);
  _devblog_migrate_article_tags($common_arguments);
  _devblog_migrate_users($common_arguments);
  _devblog_migrate_files($common_arguments);
}

Define Our Migrations

Most of the array keys are pretty self explanatory really. source_type is referring to the machine name of the content type on the Drupal 6 instance and dependencies should list the machine name of any other migrations you've defined which this migration depends on. The migrate module well this ensure they are executed in the correct order.

 'Migrate article nodes',
    'machine_name' => 'ArticleMigration',
    'source_type' => 'article_content_type', // Change this to your content type.
    'destination_type' => 'article',
    'user_migration' => 'UserMigration',
    'dependencies' => array('ArticleTagMigration'),
  );

  Migration::registerMigration($migration_class="DevblogArticleMigration", $args['machine_name'], $args);
}

/**
 * @param $common_arguments
 */
function _devblog_migrate_article_tags($common_arguments) {
  $args = $common_arguments + array(
    'description' => 'Migrate article tags',
    'machine_name' => 'ArticleTagMigration',
    'source_vocabulary' => $vid = 1, // The Vocab Id of the tags on the D6 instance.
    'destination_vocabulary' => 'tags',
  );

  Migration::registerMigration($migration_class="DrupalTerm6Migration", $args['machine_name'], $args);
}

/*
 * @param $common_arguments
 */
function _devblog_migrate_users($common_arguments) {
  $args = $common_arguments + array(
    'description' => 'User Migration',
    'machine_name' => 'UserMigration',
  );

  Migration::registerMigration($migration_class="DrupalUser6Migration", $args['machine_name'], $args);
}

/**
 * @param $common_arguments
 */
function _dhm_migrate_migrate_files($common_arguments) {
  $args = $common_arguments + array(
    'description' => 'Files migration.',
    'machine_name' => 'FileMigration',
    'source_dir' => '/home/ben/sites/devblog/sites/default/files/', // Absolute path to files folder.
    'destination_dir' => 'public://images',
  );

  Migration::registerMigration($migration_class="DevblogFileMigration", $args['machine_name'], $args);
}

Custom Migration Classes

Once you get past migrating the core fields that existing in Drupal 6 and 7 you will need to start writing your own migration classes and providing some custom logic. Below is an example of a custom node migration which maps some custom image fields and taxonomy term references.

DevblogArticleMigration

addFieldMapping('field_tags', $vid = '1')
      ->sourceMigration('ArticleTagMigration')
      ->arguments(array('source_type' => 'tid'));

    // Map the image field.
    $this->addFieldMapping('field_article_image', 'field_article_image')
      ->sourceMigration('FileMigration');

    // Set the class to be used.
    $this->addFieldMapping('field_image:file_class')
      ->defaultValue('MigrateFileFid');
  }
}

Conclusion

Using Mike Ryan's migration modules D6-D7 migrations have never been easier. I successfully managed to migrate all content on a basic site across in around a day which is significantly less time than other approaches. I've been working with the Migrate module again recently for some more complex integrations including a constant sync from an XML feed supplied by the Services module. I'll probably do a write up at some point in the near future. If you want to hire me, we're an Australian based Drupal agency and provide Drupal migration services.

Resources

Migrate Documentation Drupal to Drupal Migrate Documentation Acquia D2D Case Study Part 1 Acquia D2D Case Study Part 2

Comments

Permalink

Thanks for sharing this info!
I have been upgrading my Drupal 6 to 7 for 2 months, there were lots of work with scripts and I almost gave up.. But then my friend suggested me one tool that makes Drupal upgrade automatically - http://wparena.com/how-to/how-to-migrate-from-drupal-to-wordpress-coding-free-a-guide-for-non-programmers/

It moves only content elements without modules and theme, but still it makes the upgrade much more simple. Now, I'm almost done with the site redesigning and i'm pretty happy with the result. This tool took me several hours of upgrading while I had spent the months before. Actually, this service is developed both for programmers and non-techies and it doesn't require any software or module installation. Also, you may check whether it fits your peculiar site case by proceeding with the demo migration of 10 pages with all their entities for free. here's direct link to this site and the list of supported entities http://www.cms2cms.com/supported-cms/drupal-update

I think this will be useful for you!
Best Regards!

Permalink

I do get this error:

Class DevblogFileMigration no longer exists

Permalink

@Sathesth that usually means either the file isn't included in your .info file, the filename is wrong or maybe changed since it was last registered. If you're still having issues, i'd delete the entry in the migrate_status table.

Add new comment

The content of this field is kept private and will not be shown publicly.

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.