Customize migrations
Create your initial migrations
- Create the migrations using
drush migrate:upgrade --configure-onlyas discussed in Upgrade Using Drush - Make sure you have a
config/syncdirectory, to which the next step will write - Export the migrations using
drush config:export - Create your custom migration module
- Copy only the YML files you want to use from the
config/syncdirectory into theconfig/installdirectory of your new custom module, editing them to remove theuuidvalues and to edit the id, group, label, and other values as needed - Copy the group file the
migrate_plus.migration_group.migrate_drupal_7.ymlfromconfig/syncto theconfig/installdirectory of your new custom module, naming itmigrate_plus.migration_group.your_module.yml. You will need the group file as it contains the database settings.
Migration management
- Before installing your custom migration module, make sure all the generated migration configs from
drush migrate:upgrade --configure-onlyare deleted (Rundrush config:export, delete themigrate_plus.*config files and rundrush config:import). - Now install your custom migration module and all your filtered YML files from your modules
config/installfolder gets installed. - Now run
drush migrate:import --group=your_module --continue-on-failureto run your migration.- Note, that if you are using the Migrate Tools module, you can run
drush migrate:treeto output the migration dependency tree. But generally, thedrush migrate:import --group=your_module --continue-on-failurecommand will run the migrations in the correct order specified by the migration YML's "migration_dependencies" entry.
- Note, that if you are using the Migrate Tools module, you can run
- As you proceed with adding more files to your module's config/install directory, re-read the directory with something like
drush config-import --partial --source=modules/custom/your_module/config/install.
Rename fields when upgrading
Let’s say that you have content type A in your Drupal 7 site with fields foo, bar, and baz. Let’s also say that you want to rename the field baz to zot. These kinds of changes are quite simple to do when you are migrating using drush.
- Create the migrations using
drush migrate:upgrade --configure-onlyas instructed on the page linked above. - Run the node type and field migrations. This will generate content type A and fields foo, bar, and baz.
- Manually create field zot on the destination site. Delete the field baz that the migrations created but which you are not planning to use.
- The contributed Migrate Plus module allows migration plugins to be implemented as configuration entities, allowing them to flexibly be loaded, modified, and saved. The individual migrations generated with
drush migrate:upgrade --configure-onlycan now be inspected by navigating to admin/config/development/configuration/single/export and by selecting 'Migration' as the Configuration type. Select the migration for Nodes (A). - Copy-paste the migration to admin/config/development/configuration/single/import but change the field mapping so that the destination field will be field_zot but you still map the source from field_baz. The exact content of the migration definition will depend on the field type. To understand the anatomy of the migrations, please refer to the examples provided in the Migrate API documentation.
- Once you have imported the modified migration, you can run the migration for A nodes with Drush and verify that the data was migrated to field zot correctly.
- Repeat the mapping change for Node revisions (A) migration if you're planning to also migrate node revisions.
Another way to achieve the same result is to manually create the new field zot as described above and alter the field mapping of Nodes (A) migration by implementing hook_migration_plugins_alter().
Writing custom process plugins
If you need to define custom transformation logic (if this, then that) you might want to consider writing a custom process plugin.
The example in Migrate API documentation uses User migration as an example. The user’s language code determination needs if-else logic as described in the example and therefore the User module provides its own process plugin UserLangocode.
The example linked above describes how the process should be saved to the MODULE/src/Plugin/migrate/process directory and how it should be annotated so that it can be used. Use the UserLangcode and other process plugins as examples when writing your own!
hook_migrate_prepare_row()
If you need to define custom transformation logic, you can also implement hook_migrate_prepare_row() in your custom module and implement your logic in there.
As the API documentation of the hook describes, the hook has three arguments:
- Row $row
- MigrateSourceInterface $source
- MigrationInterface $migration
As described on the API documentation of the hook, you can use $migration->id() to limit your logic to only the desired migration.
To read a source property to a variable, use Row::getSourceProperty(), for example, if the source row would have a property called 'type', you could say $type = $row->getSourceProperty('type');
To set a completely new property that you can use in your migration definition as a source, use Row::setSourceProperty().
To make database queries to the source site, use $source->getDatabase()->query() as demonstrated in the hook API documentation.
To skip the row from being migrated, you can throw a new MigrateSkipRowException.
hook_migration_plugins_alter()
Another way to customize the migrations is to implement hook_migration_plugins_alter() in your custom module.
As described in the API documentation, this hook has one argument which is an associative array of all discovered migrations. You can alter the migrations or remove migrations that you don't want to be executed.
Migrate Plus provides a PREPARE_ROW event
If you prefer to write your custom responses to the core prepare_row hook in an object-oriented way instead of implementing the hook_migrate_prepare_row(), you can do this if you have the contributed Migrate Plus module enabled. Migrate Plus provides a PREPARE_ROW event which your event subscriber can register to. Drupal API documentation for Events. For an example of event subscriber implementation in another context, you can refer to this example from the Simple FB Connect module handbook.
Migrate and Migrate Plus Events
A (most complete) list of the migrate events you can react on :
MigrateEvents::MAP_SAVE
MigrateEvents::MAP_DELETE
MigrateEvents::POST_IMPORT
MigrateEvents::POST_ROLLBACK
MigrateEvents::PRE_ROW_SAVE
MigrateEvents::POST_ROW_SAVE
MigrateEvents::POST_ROW_DELETE
MigratePlusEvents::PREPARE_ROW
A useful implementation can be read in the constructor of class MigrateExecutable, Migrate Tool module.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion