The Drupal-to-Drupal data migration module (migrate_d2d) extends the framework provided by the Migrate module to support migration of content and data from one Drupal installation to another. It understands the core schemas of Drupal 5, Drupal 6, and Drupal 7, as well as the contributed CCK module for versions 5 and 6.

migrate_d2d provides a framework enabling you to create a custom module implementing a Drupal-to-Drupal migration to register (and potentially override) the appropriate classes for your particular scenario. With version 2.1, there is a migrate_d2d_ui module which supports configuring a simple migration without coding. This module automatically detects the Drupal source version, but may be confused if you have tables from multiple Drupal versions in one database.

Bundled with migrate_d2d is migrate_d2d_example, which demonstrates the basics of registering migration classes, as well as examples of overriding the classes to handle custom field mappings. Also see https://www.acquia.com/blog/drupal-drupal-data-migration-part-1-basics for a brief overview. https://smbjorklund.no/how-migrate-content-drupal-6-7-using-migrated2d-p... is a series of articles that take you through migration of users, taxonomy, files and nodes.

While the migrate_d2d_example is a good demonstration for the most basic migrations, an overall understanding of the underlying migrate module is extremely helpful. Time spent reading and studying the Migrate documentation will allow you to much more easily create your own custom migrations.

Class registration

The migrate_d2d classes are based on the Migrations and migration groups concept. Each migration class must be explicitly registered with an array of arguments, and you can register a class multiple times (with different machine names and different arguments to distinguish them). For example, you can register DrupalNode6Migration with one set of arguments to import articles, and another to import blog posts. Typically you will register your migrations in hook_migrate_api().

Common class arguments

Classes have names of the form Drupal{object}{version}Migration, where {object} is the type of Drupal 7 entity to create (User, Node, etc.) and {version} is the Drupal version number of the source system (5, 6, or 7). Thus, to import users from Drupal 6, you would use DrupalUser6Migration.

All migrate_d2d migration classes require the following arguments to be specified (see the child pages for details on each specific migration class):

  • machine_name: The unique machine name to assign to this migration.
  • source_version: The Drupal version of the source database (5, 6, or 7).
  • description: A brief description of the migration (e.g. "Import legacy article nodes into D7 blog nodes").
  • source_connection: Connection key for the DatabaseConnection holding the source Drupal installation. See http://drupal.org/node/1014558 for information on defining the connection.

Optional arguments that apply to all migrate_d2d migration classes:

  • source_database: As an alternative to defining your connection in settings.php, you can add the database array as an argument to your migrations.
  • group_name: The name of the migration group to hold your migrations (defaults to 'default').
  • dependencies: Migrations that must be run before this migration. Some common dependency relationships are handled by more specific arguments, but this allows you to add custom dependencies.
  • soft_dependencies: Migrations that should be run before this migration. These dependencies are not enforced, but help determine the order that migrations are listed and run.
  • format_mappings: An array mapping format IDs or machine names in the source database to format machine names in the destination. For example, in your Drupal 6 installation you may have had a format named Markdown with the ID 5 (there were no machine names in Drupal 6), while in Drupal 7 the format named Markdown Format has the machine name markdown. Thus, you could pass as an argument 'format_mappings' => array(5 => 'markdown'). Note that default mappings based on name are automatically generated - thus, if you have formats named Filtered HTML on both sides, they will be properly mapped without any work on your part.
  • source_options: An array to be passed as options to the MigrateSourceSQL constructor. The defaults are map_joinable FALSE, cache_counts TRUE, and cache_key derived from the machine name.
  • version_class: There is a helper class for each Drupal version (5, 6, or 7) used to do things like figure out what fields are available on entities. You can override this class to customize this behavior - if so, pass your class name in this variable.

A best practice is to define an array containing those arguments that will not change for any of your migrations, then append to it the class-specific arguments you need. An example of a common arguments array:

$common_arguments = array(
  'source_version' => 6,
  'group_name' => 'example',
  'source_connection' => 'legacy',
  'source_database' => array(
    'driver' => 'mysql',
    'database' => 'drupal6_db',
    'username' => 'legacy', // Ideally this user has readonly access
    // Best practice: use a variable (defined by setting $conf in settings.php, or
    // with drush vset) for the password rather than exposing it in the code.
    'password' => variable_get('example_migrate_password', ''),
    'host' => '12.34.56.78',
    'prefix' => '',
  ),
  'format_mappings' => array(
    '5' => 'markdown',
  ),
);