Some part of this page if out of date, mainly because of Migrations are plugins instead of configuration entities. This page was last updated in Feb 2015.
Setting up
You’ll need clones of Drupal 6, 7, and 8. They don’t have to be installed, just cloned.
D6: The install file so you can look at hook_schema implementation
D7: The *.install files can help you locate more information about what changed between 6 and 8 in the update functions.
D8: The entity class
D8: The source class. If it is not in core (which is likely), you will need to download yours from here. Source classes are only added to core with a full, tested migration. This will likely be the migration you are writing right now. Don't forget to add the relevant unit test as well.
Find an open issue
Visit the Migrate Drupal 6 into Drupal 8 meta issue to find an open issue to get started on.
Creating the migration config file
A good example of a complete file is core/modules/migrate_drupal/config/migrate.migration.d6_user_role.yml.
Create your new file in core/modules/migrate_drupal/config, naming it after what you are migrating.
migrate.migration.d#_name.ymlIn this example, I’m writing a D6 migration for Role.php, so I’ll name it:
migrate.migration.d6_user_role.ymlWriting the contents of the migration config file
id
This matches the last part of the file name (Drupal version and migration)
Since the file is called migrate.migration.d6_user_role.yml, the id will be:
id: d6_user_roleIf the id and the filename don't align, then the entity won't load.
source
The source class, if one exists, is found in the core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/source/d6 directory. For our example, that’s Role.php
source:
plugin: d6_user_roleExample:
Line 16 in
core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/source/d6/Role.php
/**
* Drupal 6 role source from database.
*
* @MigrateSource(
* id = "d6_user_role"
* )
*/process
Process keys are
- For configuration entities, the public properties of the entity class (minus UUID, which is generated).
- For content entities, the keys in
baseFieldDefinitions
See the handbook page for the currently available processes. The details will vary depending on the property, but you can start by listing the public properties as follows:
process:
id:
label:
weight:
permissions:Example:
Lines 42 - 77 in
core/modules/user/lib/Drupal/user/Entity/Role.php
class Role extends ConfigEntityBase implements RoleInterface {
/
* The machine name of this role.
*
* @var string
*/
public $id;
/
* The UUID of this role.
*
* @var string
*/
public $uuid;
/
* The human-readable label of this role.
*
* @var string
*/
public $label;
/
* The weight of this role in administrative listings.
*
* @var int
*/
public $weight;
/**
* The permissions belonging to this role.
*
* @var array
*/
public $permissions = array();destination
The issue told me these values, but I can verify this by looking at D8
destination:
plugin: entity
entity_type: user_roleExample:
Line 18 of core/modules/user/lib/Drupal/user/Entity/Role.php
/**
* Defines the user role entity class.
*
* @EntityType(
* id = "user_role",
* label = @Translation("Role"),
* controllers = {
* "storage" = "Drupal\user\RoleStorageController",
* "access" = "Drupal\user\RoleAccessController",
* "list" = "Drupal\user\RoleListController",
* "form" = {
* "default" = "Drupal\user\RoleFormController",
* "delete" = "Drupal\user\Form\UserRoleDelete"
* }
* },Writing integration tests for the migration (TDD)
Creating the dump file
- First, create your file in core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump. The naming convention is Drupal6EntityName.php
Example:
core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6Role.php - Set up the skeleton, being sure to change the lines indicated:
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Tests\Dump\Drupal6Role. <--Update this
*/
namespace Drupal\migrate_drupal\Tests\Dump;
use Drupal\Core\Database\Connection;
/**
* Database dump for testing role migration. <--Update this
*/
class Drupal6Role { <--Update this
/**
* @param \Drupal\Core\Database\Connection $database
*/
public static function load(Connection $database) {
[You will paste code here]
}
} - Paste the dump code:
You'll usually find the data you need in the Drupal 7 file modules/simpletest/tests/upgrade/drupal-6.filled.database.php For this example, we'll search for drupal-6.filled.database.php for the test "db_create_table('node_type'" and copy everything beginning with that line up to and including the next ->execute(); - Update the function calls:
db_create_table('role', array(becomes$database->schema()->createTable('role', array(db_insert('role')->fields(array(becomes$database->insert('role')->fields(array(
MigrateD6FilterFormatTest
Drupal6FilterFormat dump
- load the migration
- specify the dump
- prepare for migration
- run the import
- load the result
- assert it looks good
- done
Creating the Simpletests
The following directions create the stub for the tests with a single assertion. If you can, create the full test files, but if not, stub in the tests by following this example.
Test files are located in core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6. The naming convention is MigrateEntityNameTest.php
Skeleton example:
core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateNodeTypeTest.php
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Tests\d6\MigrateRoleTest <- Update this
*/
namespace Drupal\migrate_drupal\Tests\d6;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\MigrateMessage;
use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
class MigrateNodeTypeTest extends MigrateDrupalTestBase {
// add setUp
function testNodeType() {
$migration = entity_load('migration', 'd6_node_type'); <- Update this
$dumps = array(
drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6NodeType.php', <- Update this
);
$this->prepare($migration, $dumps);
$executable = new MigrateExecutable($migration, new MigrateMessage());
$executable->import();
$node_type = entity_load('node_type', 'page'); <- Update this
$this->assertIdentical($node_type->name, 'page'); <- Update this
}
}Writing migration-specific process plugins
Many migrations will require migration-specific plugins. These require deep and specific knowledge of Drupal. You should feel free to move on to the next issue and leave those plugins to others. If you want to take a shot at them, moshe and chx will be your resources.
Comments
How to start migration process?
How to start migration process?
Sorry
But I need more information to answer this question.
Missing documentation
Hey, thanks for this nice module!
I guess that what andyceo meant is, "how to perform the migration process". There's no UI in Drupal yet, so you need to perform migrations using drush.
The github module is a really good starting point to get to know migrate but that module is currently missing a readme file too (https://github.com/heddn/d8_custom_migrate).
More documentation can be found here: https://www.drupal.org/node/2574707
To resume: In order to get a list of available migrations you can run "drush migration-status".
To run the migration, you need to run "drush migrate-import csv_file". You need to make sure the file people.csv is available in "files/csv/people.csv". (or you could change the configuration path using the CMI interface on admin/config/development/configuration/single/import)
More
There is a UI, it is just
There is a UI, it is just built for migrating from D6/D7. The UI is limited. It doesn't have any options for mapping fields. But one does exist.
I see that destinationIds
I see that destinationIds were missed from the implemented .yml (that in sandbox). I assume that are automatically extracted from destination entity definition while we know that destination is an entity of type 'user_role'.
Are the destinationIds optional when destination is 'entity'?
________________
Claudiu Cristea
webikon.com
They are now optional
I made them optional six hours ago in 9fccb24f9719fc76b420b768ecbedf1a4f0c87b7 and now I removed from this docs, I will follow with the handbook soon. sourceIds will become optional as well. After all, the plugin knows what it reads/writes so it can provide Ids just fine. Eventually they might get remove completely.
OK. Thank you. I edited also
OK. Thank you. I edited also the page: migration and source ID were wrong. See revision log.
________________
Claudiu Cristea
webikon.com
No drush migrate-* commands availabe
I'm testing this out.
I've installed Drush 7 using composer and I've pulled the latest version of Drupal 8 and installed it. I wanted to test the migration in Drupal 8. When I issue commands like
drush migrate-import --helpit says:
The drush command 'migrate-import' could not be found. Rundrush [error] cache-clear drushto clear the commandfile cache if you haveinstalled new extensions.
None of the drush migrate commands are working. when I issue
H:\xampp\htdocs\d8_test>drush help --filter=migrateit says:The specified command category migrate does not exist. [error]Both
migrateandmigrate_drupalmodules are enabled in this d8 installation. what seems to be the problem?Drupal 8 Alpha doesn't
Drupal 8 Alpha doesn't support migration yet. You'll need to get the IMP distro from chx's sandbox: https://drupal.org/sandbox/chx/2105305
Go to version control and use git to clone it to your machine.
It's also worth looking at the GUI work that MikeRyan has been working on: https://drupal.org/node/2200379. I'm not sure if that has been committed yet. but the patches allow you to migrate via a user interface rather than terminal.
It's been a few weeks since I tested migrations but when I did, blocks were breaking the migration so it's worth disabling blocks on the source site, if they break your migration.
Good luck! It's pretty exciting stuff when all the settings, files and content migrate in correctly.
Sure it does
Core has migration support now. You need the drush migrate-manifest command. The manifest is a simple YAML file of migrations to run.
- d6_migration1- d6_migration2
and so on.
Its interesting to note that
Its interesting to note that Drupal 8 migrate plugin doesn't provide other
drush migrate-*but provides this (from here):drush migrate-manifest <manifest-name> --db-url=<mysql://root:pass@127.0.0.1/db>example
drush migrate-manifest manifest.yml --db-url=mysql://root:password@127.0.0.1/dbThanks chx. I saw that
Thanks chx.
I saw that massive patch the IMP team put together a few weeks ago but didn't realize it made it into core already. I'll have to get back on it and get my migrations in order. I have several sites to migrate once D8 is ready for prime time.
Andrew
Am I right Should we add
Am I right
Should we add files to core/ subfolder for migration?
It is weird and bad design in terms of security
Andriy Podanenko
web: http://druler.com
No that is wrong, this is
No that is wrong, this is documentation for core contributors who were helping write the D6 to D8 migrations for core.
If you're writing custom migrations you should put those migrations in your own modules config/install folder. If you're trying to alter core migrations, look at hook_entity_migration_alter().
the hook
It's hook_migration_load() isn't it?
I should have checked :)
I should have checked :) you're right. hook_ENTITY_TYPE_load