Note: This documentation is for Drupal 7 contrib Migrate module, the Drupal 8 core Migrate API documentation can be found here.

To develop migration processes based on the Migrate framework, you will need to create your own Migration classes in a custom module.

Examples

The Migrate module comes bundled with some working examples of custom migration modules. The best place to start is with migrate_example. The first place to look here is migrate_example/beer.inc, which can be read straight through from top to bottom as a tutorial introduction to the key migration concepts. To become familiar with the general infrastructure of a migration module, also look at migrate_example.info, migrate_example.migrate.inc and migrate_example.module (which would be empty if it didn't have to explain why it's empty!).

The wine.inc file demonstrates more advanced techniques, as well as providing test cases for simpletests. There is also a migrate_example_baseball module, demonstrating dynamic registration of migrations as well as import from CSV files, and a migrate_example_oracle module demo, showing how to import from an Oracle database server.

Implementing your own migration

Create a directory in your modules directory (typically sites/all/modules/custom) and add .info, .migrate.inc, and .module files. For example, if migrating from a legacy CMS named XYZ, you might create a migrate_xyz folder to hold the files below.

migrate_xyz.info

In your .info file you need to specify which modules your migration depends on to be able to run, and what other migration files you will be using. For example:

name = "Migrate from XYZ"
description = "Module to migrate my old site content to Drupal 7"
package = "Migration"
core = 7.x

dependencies[] = migrate

;  include the files that contain your Migrate classes
files[] = user.inc
files[] = forum.inc
files[] = gallery.inc
files[] = roles.inc

You must list any file here which contains migration classes you're implementing, for Drupal's class registry to be able to find them. When changing the list of files here, or adding or renaming classes within the .inc files, you need to clear the cache to update the registry with your changes.

migrate_xyz.migrate.inc

For the Migrate module to recognize classes defined by your module, you must implement hook_migrate_api(). The best place to do this is in migrate_xyz.migrate.inc - the function will then only be loaded when necessary.

Because the name of this file is the module name plus '.migrate.inc', when hook_migrate_api is invoked by the Migrate module this file is automatically loaded - thus, you don't need to implement your hook in the .module file.

In your hook_migrate_api() implementation, you will return an array of information about your migration code:

  • api: the version of Migrate your code supports (currently 2 is the only supported version).
  • groups: an array keyed by group machine names, with arrays of arguments (including in particular 'title', the user-visible name of the group).
  • migrations: an array keyed by migration machine names, with arrays of arguments (including in particular 'class_name', the name of the Migration class you've implemented). See Class registration for more details.
  • destination handlers: an array with the name of any destination handler classes your module implements.
  • field handlers: an array with the name of any field handler classes your module implements.

Example:

/**
 * @file
 * Declares our migrations.
 */
    

/**
 * Implements hook_migrate_api().
 */
function migrate_xyz_migrate_api() {
  $api = array(
    'api' => 2,
    'groups' => array(
      'xyz' => array(
        'title' => t('XYZ Migrations'),
      ),
    ),
    'migrations' => array(
      'XyzUser' => array(
        'class_name' => 'MigrateXyzUserMigration',
        'group_name' => 'xyz',
      ),
      'XyzArticle' => array(
        'class_name' => 'MigrateXyzArticleMigration',
        'group_name' => 'xyz',
      ),
    ),
  );
  return $api;
}

migrate_xyz.module

This file will usually be empty, unless you have a need to implement any Drupal hooks (for example, if your migration module is going to present a UI, you would at least have a migrate_xyz_menu() function here).

View your migration classes

When your module is enabled, you will be able to view the available migrations using the Migrate UI dashboard or the drush migrate-status command:

$ drush migrate-status
Group: xyz Total  Imported Unprocessed Status Last imported       
XyzUser    28     28       0           Idle   2012-04-05 22:26:33 
XyzArticle 2102   2102     0           Idle   2012-04-02 16:00:18 

Troubleshooting

If you're not able to see your newly defined migration(s), here's how you can troubleshoot:

  • ensure you've correctly implemented hook_migrate_api()
  • ensure your hook_migrate_api() implementation follows the naming convention MODULENAME_migrate_api() and is located in a file named MODULENAME.migrate.inc
  • clear all caches
  • enable the Migrate UI, go to admin/content/migrate/configure and click 'Register statically defined classes'

Comments

drewish’s picture

I keep having issues with autoload not finding classes. The quickest way to sort it out seems to be truncating {autoload_registry}, {autoload_registry_file} and {cache} then loading hitting /admin/build/modules and submitting the form.

GDrupal’s picture

There is another thing if you are using Autoload on Drupal 6... Autoload will not recognize your class if you do not declare it like this in your *.module file, assuming that the class definition is in the file "my_migration_class.inc" :

my_migration.module


/**
 * Implements hook_autoload_info().
 */
function my_migration_autoload_info() {
  $classes['MyMigrationClass'] = array(
    'file' => 'my_migration_class.inc',
  );
}

Beware! I struggle big time until I include this lines in my migration module on Drupal 6...

----------------------------------------------------------
G.A. Martin, Drupal Developer.

mikeryan’s picture

To use Migrate on Drupal 6, you need to be using Autoload V2. With V2, there's no need to implement hook_autoload_info(), you just need to put the files containing your classes into your .info file.

GDrupal’s picture

Mike I have tried that but was not working for me (using Pressflow 6.22 + Ubercart +Localization)... until I include the hook... perhaps If someone has the same issue the hook option will help.

----------------------------------------------------------
G.A. Martin, Drupal Developer.

soulston’s picture

There was a great presentation at DrupalCamp North West by Elliot Ward (Eli-T). http://vimeo.com/54448150. This covers some of the basics of doing a migrate from Drupal to Drupal.

johanv’s picture

... double check that your main .inc file is called 'migrate_xyz.migrate.inc'. Yes, 2 times migrate :-)