Migrating content from different sources to Drupal

June 18, 2021

Tags: Technologies, Tech Trends, Managed Teams

Table of contents

Quick Access

Sometimes we need to migrate data from a known source to our site in **Drupal 7**, this is a task that can take several hours if you have no knowledge of migration and the possible data sources. The **Migrate** Drupal module shortens the hours we work and presents a very simple and powerful interface. Let's look at an example of how we can migrate from a database table with the necessary data to create nodes of a content type on our site. For this example I have a content type called **Activities** where I have a title, body and image only. Considering the fields of my content type, i can map the data contained in the "activities" database table that i need to migrate. drupal migrate With this in mind, we will enable the **Migrate** module and then **Migrate UI** module which offers an interface for managing migration. [prism:javascript] drush en migrate -y drush en migrate_ui -y [/prism:javascript] Let's write the code! We create a custom module called *migrate_activities* and include the migrate module as a dependency. In migrate_activities.info: [prism:javascript] dependencies[] = migrate [/prism:javascript] Our new module will have 4 files, as seen in the following image: drupal migrate The *migrate_activities.module* file this time will be empty, just add a description. And why it is empty? Because this time we'll be using the hook hook_migrate_api (), which will allow us to record different migration groups (in this example we only need to create one group). This hook is detected in migrate_activities.migrate.inc file, and its contents are generally seen as follows: [prism:javascript] /** * Implements hook_migrate_api(). */ function migrate_activities_migrate_api() { $api = array( 'api' => 2, 'groups' => array( 'activities_group' => array( 'title' => t('Activity Migrations'), ), ), 'migrations' => array( 'activities' => array( 'class_name' => 'MigrateActivities', 'group_name' => 'activities_group', ) ), ); return $api; } [/prism:javascript] This hook returns the group information migration, with their names and classes. In our case we will need the **MigrateActivities** class. This class is defined in the *activities.inc * file, so we include it as a required file in the *migrate_activities.info* file. [prism:javascript] files[] = ‘activities.inc’ [/prism:javascript] It is very important to extend this class from the Migrate class son, so our first line of code will look like this: [prism:javascript] /** * Class MigrateActivities */ class MigrateActivities extends Migration { public function __construct($arguments) { parent::__construct($arguments); } [/prism:javascript] The array of arguments passed as a parameter to the constructor of the class include the name of the group of migration and can also include other elements as needed. Before continuing, it is necessary to know the source of data that we want to migrate. The Migrate module provides an interesting list of possible sources we can use: [prism:javascript] MigrateSourceSQL MigrateSourceList MigrateSourceMultiItems XML-based sources MigrateSourceCSV JSON-based source classes MigrateSourceMSSQL MigrateSourceOracle HTML and other files as sources MigrateSourceMongoDB [/prism:javascript] See https://www.drupal.org/node/1006986. For this example, I'll use the **MigrateSourceSQL** class because the migration will be from a SQL database. **IMPORTANT**: You must create a database connection to the database we want to migrate in the Drupal settings file, for example: [prism:javascript] 'migrate_db' => array( 'default' => array( 'database' => 'migrate', 'username' => 'root', 'password' => root, 'host' => 'localhost', 'port' => '', 'driver' => 'mysql', 'prefix' => '', ), ), [/prism:javascript] With this, we can edit the **MigrateActivities** class. Under the builder put the following code: [prism:javascript] $query = Database::getConnection('default', 'migrate_db') ->select('data', 'a') ->fields('a', array('id', 'title', 'description', 'imageUrl')); $fields = array( 'id' => 'Unique ID for each source data row', 'title' => 'The activity title', 'description' => 'The activity description', 'imageUrl' => 'An image url of the activity' ); $this->source = new MigrateSourceSQL($query, $fields); $this->destination = new MigrateDestinationNode('activities'); [/prism:javascript] What I have done here is to tell Drupal to establish a connection to the **migrate_db** database, and then a select query to the table data, then declaring an array called fields with the fields that will use from the table and declare the tarjet defined, in my case the tarjet is the content type activities, because i want to create new nodes of that content type. The next step is to map the source data to the destination for which we do the following: [prism:javascript] $this->map = new MigrateSQLMap($this->machineName, array( 'id' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, ) ), MigrateDestinationNode::getKeySchema() ); // Mapped fields $this->addFieldMapping('title', 'title') ->description(t('Mapping json object name in source to node title')); $this->addFieldMapping('body', 'description'); $this->addFieldMapping('field_activity_image', 'imageUrl'); [/prism:javascript] The **id** used is the id of the table data which have declared in the **$fields** array, with this data the Migrate module can keep track of the migrated data and missing ones. Then I make the map of the fields of the content types with the fields declared in the $fields array. We enable our module and headed to the interface migration: [prism:javascript] admin/content/migrate/configure [/prism:javascript] On this page, click in the **Register statically defined clasess** button to register our migration automatically thanks to hook_migrate_api(). drupal migrate On the dashboard (admin/content/migrate) shows something like this: drupal migrate Clicking on the name of the group, we see the migration table: drupal migrate In the picture below a list of available options is shown to migration, which are very well explained. drupal migrate Also, if you click on the title of the task, we see a new page that contains the mapping we do, and the other possible fields available for mapping: drupal migrate Back to the table and choose the option to import and wait for the process to finish. drupal migrate drupal migrate Once the process is complete, we will have new nodes of Activities. As an example, I created a simple view to show the results of migration: drupal migrate Migrate module of Drupal 7 gives us the ability to migrate data from different sources to create on our site entities we know as Users, nodes, taxonomies, etc. This module saves us many hours of work and it is essential in any project where you need to migrate content. Reference: https://www.drupal.org/migrate

Let's work together!