Moving a MySQL database in Drupal is about keeping everything structured while upgrading, switching servers, or merging databases.
A well-planned approach ensures a smooth and well-executed transition.
Preparation is key:
- Backup the data to keep everything secure.
- Understand the database structure to map fields correctly.
- Choose the right migration method based on the site's needs. Some databases work with a simple export/import, while others benefit from structured migrations.
Drupal provides tools like Drush and the Migrate API to simplify the process. The right approach depends on the site's size, structure, and hosting environment.
With careful planning and the right tools, the migration process keeps everything intact and running smoothly.
Let us walk through the key steps to ensure a seamless transition.
Understanding the source data
Before migrating, take a close look at the database. Check how tables are organized, how they connect, and where different fields come from. A clear database map helps everything move smoothly.
Start by identifying tables, primary keys, and relationships. Some data, like user accounts and content, is easy to migrate, while others—like custom fields, revisions, or module-specific tables—might need extra attention.
Look at the code and configurations to see where certain data is stored. If custom modules save information in unique ways, noting these details early makes the migration process easier.
Finally, match the source tables with Drupal’s content types, users, taxonomy, and configurations. This ensures everything ends up in the right place, keeping the site running as expected.
Setting up the migrate source database
Since the data is coming from a MySQL database, Drupal’s database source plugin allows for direct migration.
To get started, the source database needs to be added to Drupal’s configuration, ensuring that the migration process has access to both the original and destination databases.
This setup involves defining key details such as the database name, username, password, host, and driver. Once these details are configured, Drupal can connect to the source database and pull data without affecting the live site.
With the source database properly set up, the next step is to configure the migration to map data correctly from its current structure to the new one in Drupal.
$databases[migrate]['default'] = array(
'database' => "source_database_name",
'username' => "source_db_user",
'password' => "source_db_password",
'host' => "source_db_host",
'driver' => "source_db_driver",
'port' => "source_db_port",
'prefix' => "",
);
Source database structure
Assume the source database has the following tables and fields:
articles Table
Target Drupal content type
In Drupal, the target content type for articles will map to the following fields:
Title: Mapped from articles.Title.
Article Type: Mapped from articles.ArticleType.
Body: Mapped from articles.Body.
Status: Mapped from articles.Status.
Defining the source database plugin
To migrate an article table into Drupal’s article content type, a source database plugin is needed. This plugin connects to the source database, retrieves the data, and prepares it for migration.
It ensures that each field from the original database matches the right place in Drupal. If the data structure is different, the plugin helps adjust it so everything fits correctly.
Once the plugin is set up, the migration process can use it to pull data smoothly, making sure nothing is missed or misplaced.
Here's how to properly define the source database plugin in src/Plugin/migrate/source/Article.php:
<?php
namespace Drupal\non_drupal_source_migrate\Plugin\migrate\source;
use Drupal\migrate\Plugin\migrate\source\SqlBase;
/**
* Article migrate source plugin.
*
* @MigrateSource(
* id = "article",
* source_module = "non_drupal_source_migrate"
* )
*/
class Article extends SqlBase {
/**
* {@inheritdoc}
*/
public function query() {
// Source data is queried from 'Articles' table.
$query = $this->select('Articles', 'f')
->fields('f', [
'Id',
'ArticleType',
'Title',
'Status',
'Body',
]);
return $query;
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = [
'Id' => $this->t('Id'),
'ArticleType' => $this->t('ArticleType'),
'Title' => $this->t('Title'),
'Status' => $this->t('Status'),
'Body' => $this->t('Body'),
];
return $fields;
}
/**
* {@inheritdoc}
*/
public function getIds() {
return [
'Id' => [
'type' => 'integer',
'alias' => 'f',
],
];
}
}
Setting up the migration plugin
To migrate data from the source database, a custom source plugin needs to be set up. This helps Drupal recognize and process the data correctly.
- Namespace and dependencies
The migration plugin needs a namespace and should use Drupal’s SqlBase class. This allows it to connect with the source database and retrieve data. - Annotations
- @MigrateSource tells Drupal this is a migration plugin.
- id is a unique name for the plugin.
- source_module is the name of the custom module handling the migration.
- Methods to handle data
- query(): Defines how data is selected from the source database.
- fields(): Lists all fields being migrated, with names and labels.
- getIds(): Defines the unique identifier (like an ID field) to keep track of records.
Once these steps are in place, the plugin can pull data smoothly and ensure everything is migrated properly into Drupal.
Define the migration YAML file
With the source database connection and plugin set up, the next step is creating the migration YAML file. This file outlines how data will be moved from the source database to Drupal, specifying the structure and field mappings.
The YAML file includes:
- Migration ID – A unique name for the migration.
- Source settings – Defines where the data is coming from (using the custom source plugin).
- Destination settings – Specifies where the data will be stored in Drupal (such as content types or taxonomy terms).
- Field mappings – Matches source fields to their corresponding Drupal fields.
This file is placed in the module’s config/install directory. Once configured, it allows Drupal’s migration system to understand how to process and transfer data efficiently.
id: article
label: 'Article'
migration_group: non_drupal_migration
source:
plugin: article
key: migrate
process:
title: Title
field_article_type:
plugin: static_map
source: ArticleType
map:
1: regular
2: expert
body/value: Body
body/format:
plugin: default_value
default_value: enriched
moderation_state:
plugin: static_map
source: Status
map:
0: archived
1: published
2: draft
destination:
plugin: 'entity:node'
default_bundle: article
ID and label:
- id: Unique identifier for the migration .
- label: Human-readable name for the migration.
Migration group:
- migration_group: Groups related migrations together. Ensure this matches the group you have defined.
Source:
- plugin: The ID of the source plugin defined earlier (article).
- key: The database connection key from settings.php (migrate).
Process:
- Maps source fields to destination fields in Drupal. Uses various plugins for data transformation.
- title: Direct mapping from Title field.
- field_article_type: Uses static_map to map ArticleType values to specific terms (regular and expert).
- body/value: Direct mapping from the Body field.
- body/format: Sets a default format for the Body field using default_value.
- moderation_state: Maps Status values to moderation states (archived, published, draft) using static_map.
Destination:
- plugin: Specifies the destination as an entity of type node.
- default_bundle: Specifies the content type (article).
Running the migration
After setting up the migration YAML file, the next step is to import the configuration and run the migration using Drush.
First, import the migration configuration so Drupal recognizes it.
Then, check the list of available migrations to ensure everything is set up correctly.
Once confirmed, run the migration to transfer data from the source database into Drupal.
This process moves the content while keeping its structure intact, ensuring a smooth transition.
Import the migration configuration
Use the following drush command to import the migration configuration:
drush cim --partial --source=modules/custom/non_drupal_source_migrate/config/install/
Run the migration
Execute the migration with the following Drush command:
drush migrate-import article
Verifying the migration
Once the migration is complete, check your Drupal site to make sure everything has been imported correctly.
Go to the content listing page and look for the migrated articles. Verify that all the data is there and matches the source database.
This step ensures that the migration was successful and that the content appears as expected.
Quick recap
- Analyze the source data – Understand table structures and relationships.
- Set up the source database – Add the database configuration in settings.php.
- Define the source database plugin – Create a class that extends SqlBase.
- Create the migration YAML file – Structure the migration and map fields.
- Run the migration – Use Drush commands to import and execute the migration.
- Verify the migration – Check the imported content in Drupal to confirm everything is in place.
Wrapping up
Migrating a MySQL database to Drupal is all about taking it step by step. With a clear understanding of the data structure, a well-planned migration setup, and the right tools, the process becomes smooth and predictable.
Each migration brings something new—sometimes a unique data structure or an unexpected format.
These details help refine the approach and build a deeper understanding of how data moves. Over time, recognizing patterns makes migrations even more efficient.
Here’s something useful: Drupal’s migration system is repeatable, allowing multiple test runs before finalizing, ensuring accuracy and fine-tuning the process without affecting the live site.
Next, we’ll look at one-to-many relationships in migrations— Migrating relational data into Drupal paragraphs.