|
/SW/business/Drupal:
Drupal Migrate Module Basics
The Drupal migrate module[1] is an impressive tool for migrating databases from other web applications (or anywhere, really) into the Drupal database. It even has fairly impressive documentation[2], but not unlike a lot of other big chunks of documentation, it can be hard to extract from the documentation where to start in creating a simple functional example of the migrate module at work. Hopefully this example will help to fill that gap a little.
First install and enable the migrate family of modules in a sandbox Drupal site:
drush dl migrate migrate_example migrate_extras migrate_ui
drush en migrate migrate_example migrate_extras migrate_ui
If you then point your browser at:
drupal/?q=admin/content/migrate
you will see the migrate module's UI, which shows a couple of example migrations ("beer" and "wine") already coded and setup for you by the migrate_example sub-module. You can play with importing and rolling back data with the UI, or with drush:
drush help --filter="migrate"
To create your own migration, you need to create a custom module containing the migrate code. Using a MySQL database from another application, and based upon the beer.inc example from migrate_example, I was able to get a working migrate setup with three fairly small files in a new sub-module called "migrate_test" in sites/all/modules/migrate/migrate_test/ :
sites/all/modules/migrate/migrate_test/migrate_test.module:
2, ); return $api; }
sites/all/modules/migrate/migrate_test/migrate_test.info:
name = "Migrate Test" description = "My migration data." package = "Development" core = 6.x php = 5.2 dependencies[] = taxonomy dependencies[] = imagefield dependencies[] = comment dependencies[] = migrate dependencies[] = content dependencies[] = date dependencies[] = migrate_extras files[] = migrate_test.module files[] = langex.inc ; Information added by drupal.org packaging script on 2011-09-18 version = "6.x-2.2" core = "6.x" project = "migrate" datestamp = "1316388105"
sites/all/modules/migrate/migrate_test/langex.inc:
'mysql', 'database' => 'langex', 'username' => 'langex', 'password' => 'anypass', 'host' => 'localhost', 'prefix' => '', )); /** * To define a migration process from a set of source data to a particular * kind of Drupal object (for example, a specific node type), you define * a class derived from Migration. You must define a constructor to initialize * your migration object. By default, your class name will be the "machine name" * of the migration, by which you refer to it. Note that the machine name is * case-sensitive. * * In any serious migration project, you will find there are some options * which are common to the individual migrations you're implementing. You can * define an abstract intermediate class derived from Migration, then derive your * individual migrations from that, to share settings, utility functions, etc. */ abstract class LangexMigration extends Migration { public function __construct() { // Always call the parent constructor first for basic setup parent::__construct(); // With migrate_ui enabled, migration pages will indicate people involved in // the particular migration, with their role and contact info. We default the // list in the shared class; it can be overridden for specific migrations. $this->team = array( new MigrateTeamMember('John Doe', 'john.doe@gmail.com', t('contractor')), new MigrateTeamMember('Larry Brewer', 'lbrewer@example.com', t('Implementor')), ); } } /** * There are four essential components to set up in your constructor: * $this->source - An instance of a class derived from MigrateSource, this * will feed data to the migration. * $this->destination - An instance of a class derived from MigrateDestination, * this will receive data that originated from the source and has been mapped * by the Migration class, and create Drupal objects. * $this->map - An instance of a class derived from MigrateMap, this will keep * track of which source items have been imported and what destination objects * they map to. * Mappings - Use $this->addFieldMapping to tell the Migration class what source * fields correspond to what destination fields, and additional information * associated with the mappings. */ class LangexUserMigration extends LangexMigration { public function __construct() { // The basic setup is similar to BeerTermMigraiton parent::__construct(); $this->description = t('Language Exchange Network users'); $this->map = new MigrateSQLMap($this->machineName, array('userid' => array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Account ID.' ) ), MigrateDestinationUser::getKeySchema() ); $query = Database::getConnection('default', 'for_migration') ->select('users', 'u') ->fields('u', array('userid', 'name', 'username', 'password', 'email_address', 'sex', 'signup_date')); // $this->source = new MigrateSourceSQL($query); $this->source = new MigrateSourceSQL($query, array(), NULL, array('map_joinable' => FALSE)); $this->destination = new MigrateDestinationUser(); // One good way to organize your mappings is in three groups - mapped fields, // unmapped source fields, and unmapped destination fields // Mapped fields // The migrate module automatically converts date/time strings to UNIX timestamps. $this->addFieldMapping('created', 'signup_date'); $this->addFieldMapping('pass', 'password'); $this->addFieldMapping('mail', 'email_address'); $this->addFieldMapping('name', 'username'); // Unmapped source fields $this->addFieldMapping(NULL, 'name') ->issueGroup(t('DNM')); $this->addFieldMapping(NULL, 'sex') ->issueGroup(t('DNM')); // Unmapped destination fields // This is a shortcut you can use to mark several destination fields as DNM // at once $this->addUnmigratedDestinations(array('theme', 'signature', 'access', 'login', 'timezone', 'language', 'picture')); } }
Note that this is a "cross-database migration"[3]. The source data and the destination data are located on the same MySQL server, but in different databases.
[1] https://drupal.org/project/migrate
[2] https://drupal.org/node/415260
[3] https://drupal.org/node/1014558
posted at: 09:13 | path: /SW/business/Drupal | permanent link to this entry