On this page
- Installing Drush with Composer
- Required Migration modules
- Optional migration modules
- Define the source database
- Generating migrations using migrate:upgrade
- Running specific migrations using migrate-manifest
- Notes for Acquia Dev Desktop users
- Reference of Drush migration commands
- migrate:upgrade (no alias)
- Basic example
- Options
- migrate:status (ms)
- Basic example
- migrate:import (mi)
- Basic examples
- Options
- Common use cases
- migrate:rollback (mr)
- Basic examples
- migrate:stop (mst)
- Basic example
- migrate:reset-status (mrs)
- Basic example
- migrate-manifest (no alias)
- migrate:messages (mmsg)
- Basic example
- migrate:fields-source (mfs)
- Basic example
- migrate:tree (no alias)
- Basic example
Upgrade using Drush
Drush is a command line shell and scripting interface for Drupal. Upgrading to Drupal 9 or higher using Drush is an alternative to using the browser user interface. Upgrading using Drush is very useful when migrating complex sites as it allows you to run migrations one by one and it allows rollbacks.
Installing Drush with Composer
Drupal 8 or higher sites can be built using Composer. The recommended Composer project doesn't have Drush listed as a dependency, you can install Drush from the command line as follows:
composer require drush/drush
This will give you the latest (stable) Drush which should be compatible with a recent Drupal. For more information about this, read the Drush and Drupal version compatibility matrix.
To check your version of Drush, use
drush --version
Required Migration modules
To run the upgrade with Drush you will need these two contrib modules:
- Migrate Upgrade: Use this module to use migrations as a configuration. This is a common practice but is not required by Drupal core.
- Migrate Plus: Provides extensions to core migration framework functionality, required by Migrate Upgrade.
You can download the two modules as follows:
composer require drupal/migrate_upgrade drupal/migrate_plus
Enable the modules:
drush install migrate migrate_drupal migrate_upgrade migrate_plus
Note: Since Drush 10.4, most Migrate Tools commands are included in Drush, except for the migrate:tree
command which shows a tree of migration dependencies, which you can get by installing the module. The code-base that made its way into Drush was from an earlier and simpler fork of the Migrate Tools code. For example, Drush does not support migrate plus config entities or provide a progress bar. Over time, the Drush team continues to add features and some of this might become incorporated upstream.
IMPORTANT: Pay close attention to selecting the correct version for each of the three contributed modules. Please refer to the project page for selecting a version compatible with your version of Drupal core.
For more information on the different upgrade modules, please refer to the list of upgrade modules.
Optional migration modules
Visit Drupal 9 (or later) migrate modules for a list of further migration modules.
Define the source database
This is an example of how to define the database connection details for your Drupal 6 / 7 source site. If your source site uses a database prefix, be sure to provide the prefix. You will need to connect to both the local development database (default
) as well as the source database (D6 or D7). The following is an example of how to do this with Lando. The example includes the default database set up for completeness.
Note: It is important to name your migrate database key migrate
to avoid issues, see Getting 'Field discovery failed for Drupal core version 7.' when migrating.
DDEV: Set up database and source credentials in settings.php
Start up both the source web site (Drupal 7) and target web site (Drupal 10) in separate DDEV instances. Enter the D7 credentials in the Drupal 10 settings.php
, using the Docker containers listed during start up, for example ddev-drupal7-db
and ddev-drupal7-web
, shown during start up. See Upgrade using web browser > Example values for DDEV for an example.
Lando: Set up database and source credentials in settings.php
$databases['default']['default'] = [
'database' => 'drupal8',
'username' => 'drupal8',
'password' => 'drupal8',
'prefix' => '',
'host' => 'database',
'port' => '3306',
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'driver' => 'mysql',
];
$databases['migrate']['default'] = [
'database' => 'drupal7db',
'username' => 'drupal7db',
'password' => 'drupal7db',
'prefix' => '',
'host' => 'd7db',
'port' => '3306',
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'driver' => 'mysql',
];
Example .lando.yml
name: mywebsite
recipe: drupal8
config:
webroot: web
# Create Drupal 7 database service, consider adding phpmyadmin
services:
d7db:
type: mariadb
creds:
user: drupal7db
password: drupal7db
database: drupal7db
portforward: true
Import the Drupal 7 database, assuming the database dump file is called mywebsite_db.sql.gz
and in the current folder:
lando db-import --host=d7db --user=drupal7db mywebsite_db.sql.gz
Inspiration from https://github.com/thinktandem/migration_boilerplate.
Generating migrations using migrate:upgrade
Drush adds commands such as drush migrate:status
and drush migrate:import
. A full list of the migrate-related Drush commands can be found at the bottom of this page.
If you try drush migrate:status
without doing anything else you won't see any migrations available to run. That's because the individual migrations have to first be created based on your source database. Since Migrate has no idea what source to use, no migrations have been created yet.
To generate the migrations you will need the Drush command drush migrate:upgrade
which is provided by the contributed Migrate Upgrade module.
You most probably want to only generate individual migrations so that you can run them one by one. If this is the case, you need to use the --configure-only
option.
The --legacy-db-key
option allows you to use a $databases array, with a matching key, defined in settings.php:
drush migrate:upgrade --legacy-db-key=migrate --legacy-root=https://example.com --configure-only
'https://example.com' is the root of your source site. If the legacy site is on the local filesystem, you can use a file path to the Drupal root directory as the value for this option. The value that you supply here will be prepended to the paths of the individual files to locate and import them.
Use --legacy-db-url
for a remote database:
drush migrate:upgrade --legacy-db-url=mysql://user:password@server/db --legacy-root=https://example.com --configure-only
where
- 'user' is the username of the source database
- 'password' is the source database user's password
- 'server' is the source database server
- 'db' is the source database
If your source site uses a table prefix in the database table names, you will need to add that as an additional argument as follows. In this example, the database prefix is 'drupal_'
drush migrate:upgrade --legacy-db-url=mysql://user:password@server/db --legacy-db-prefix=drupal_ --legacy-root=https://example.com --configure-only
If you don't use the --configure-only
option, drush migrate:upgrade
will first generate and then execute all migrations.
After running migrate:upgrade
with the --configure-only
parameter, you run migrate:status
to see the list of possible migrations:
drush migrate:status
Then you can review and selectively execute these migrations. To perform the migrations individually run the:
drush migrate:import <migration name>
There are several Drupal 6 and Drupal 7 migrations that are always created. If you are upgrading from a Drupal 6 site you will see some Drupal 7 migrations when running some drush commands, such as drush migrate:status
, and vice versa if you are upgrading from Drupal 7 you will see some Drupal 6 migrations when running some drush command. To avoid seeing those simply use the --tag=
option on the drush command:
drush migrate:status --tag='Drupal 7'
To perform all the migrations in the list, run the:
drush migrate:import --all
To perform only Drupal 7 migrations, run:
drush migrate:import --tag='Drupal 7'
Alternatively, if you followed the guide Customize migrations when upgrading to Drupal 9 (or later), and created a custom migration module, you can also perform the migration with an additional group annotation:
drush migrate:import --group=your_module --continue-on-failure
This way you only migrate the migrations you defined in your custom migration modules config/install
folder.
The --continue-on-failure
will additionally prevent your migration from canceling after a failed migration. This way you can do a full migration, check the failed migrations, and implement custom processing for the failed migrations inside your custom module.
Running specific migrations using migrate-manifest
It is also possible to use a manifest file to set up a specific set of migrations. This lets you run groups of migrations in a reproducible manner. For this method, you also need the Migrate Manifest module. With Migrate Manifest, you can get a complete list of available migrations using the following commands:
drush migrate:template:list
The desired migrations are defined as a YAML file as shown in the example below. You only need to list the migrations you need. Migrate Manifest will ask you to add additional migrations that are needed to resolve any dependencies. Migrations can be listed in any order, they will be executed in the correct order based on the dependencies.
# user
- d6_user
- d6_user_profile_field
- d6_user_profile_field_instance
- d6_user_profile_entity_display
- d6_user_profile_entity_form_display
- d6_profile_values:user
- d6_filter_format
- d6_user_role
- d6_user_picture_entity_display
- d6_user_picture_entity_form_display
- d6_user_picture_file
- d6_user_picture_field
- d6_user_picture_field_instance
# taxonomy
- d6_taxonomy_vocabulary
- d6_taxonomy_settings
- d6_taxonomy_term
# nodes
- d6_node
- d6_node_revision
- d6_node_type
- d6_view_modes
- d6_filter_format
- d6_field_instance_per_form_display
- d6_field_instance_widget_settings
- d6_field_formatter_settings
- d6_field_instance
- d6_field
- d6_field_settings
- d6_node_settings
- d6_cck_field_values:*
- d6_cck_field_revision:*
# taxonomy fields
- d6_term_node_revision
- d6_term_node
- d6_vocabulary_entity_display
- d6_vocabulary_entity_form_display
- d6_vocabulary_field_instance
- d6_vocabulary_field
# blocks
- d6_block
- d6_menu
# custom blocks
- d6_custom_block
- d6_filter_format
# book
- d6_book
- d6_book_settings
# file migrations are configurable, see https://www.drupal.org/node/2257723
- d6_file:
source:
conf_path: sites/assets
destination:
source_base_path: destination/base/path
destination_path_property: uri
Place the manifest file in a location that is accessible when running Drush. Storing it in your version control system is recommended so that you can track changes to your migrations.
Make sure that modules used by the migrations listed in the manifest file exist and are enabled on your source site (e.g. field module for d6_field) Otherwise, there will be errors when the migrations are executed.
The migrations defined in the manifest file are executed from the command line as shown below. Replace the database URL and path to manifest file with appropriate values (like migrate:upgrade
, migrate-manifest will accept a MySQL URL or settings.php array key):
drush migrate-manifest --legacy-db-url=mysql://d6user:d6pass@localhost/drupal_6 manifest.yml
Notes for Acquia Dev Desktop users
If you use Acquia Dev Desktop and have your Drupal 6 site in Dev Desktop, the default database credentials are drupaluser
with an empty password and the 33067 port for the database on the 127.0.0.1 IP address. Altogether that leads to --legacy-db-url=mysql://drupaluser:@127.0.0.1:33067/drupal_6
the commands assuming the database name is drupal_6
. Run drush status
if you are having trouble connecting in order to verify these values.
Reference of Drush migration commands
migrate:upgrade (no alias)
Provided by the Migrate Upgrade project. Use this to run an upgrade from Drupal 6 / 7. This command will generate migration configurations based on the source site's configuration and content.
Refer to the examples earlier on this documentation page.
Basic example
drush migrate:upgrade --legacy-db-key=migrate
Options
- legacy-db-url: Database connection information for the source database.
- legacy-db-prefix: Database table prefix for the source database.
- legacy-root: Path to the source site, this is used to transfer content from the files directory. If the files are private then a local file path must be specified, for public files http(s) will work as well.
- configure-only: Use this to create migration configurations only. When this option is set, migrations will be generated so that they can be executed individually with 'drush migrate:import'.
migrate:status (ms)
Included in Drush since 10.4.0. Use this to get the list of all migrations with their current status. Use the --group or --tag option to filter the results.
Basic example
drush migrate:status
migrate:import (mi)
Included in Drush since 10.4.0. Use this to perform one or more migration processes. This is normally used with custom migrations from non-Drupal sources. For example, if you've created and imported a custom migration configuration, this command can be used to run it.
Basic examples
drush migrate:import migration_id
drush migrate:import --tag='Drupal 7'
drush migrate:import --group=files
Options
- all: Run all migrations currently configured.
- group: Run all migrations belonging to a particular group.
- limit: Limit the number of items to process in each migration.
- feedback: Frequency of progress messages, in items processed.
- idlist: Comma-separated list of source IDs to import.
- update: Migrate new items as well as previously migrated items that have been updated on the source.
- force: Force an operation to run, even if all dependencies are not satisfied.
Common use cases
- When
migrate:upgrade --configure-only
is used, configuration entities are created. The default behavior of the new Drupal site is to not allow existing configuration entities to be overwritten,migrate:upgrade
cannot be used to run a migration aftermigrate:upgrade --configure-only
is used. Usemigrate:import
instead. - When a custom migration is created and imported (either via the configuration management UI or
drush config:import
), usemigrate:import
to run the migration. - Use Migrate Devel for troubleshooting errors during import. Example:
drush migrate:import migration_id --migrate-debug-pre
.
Pro tip: If you've imported a custom migration configuration and you need to update it and re-import it, use the Configuration Update Manager module.
migrate:rollback (mr)
Included in Drush since 10.4.0. Use this to roll back a migration. This is normally used for testing or if you had issues and need to start over. Use this with the id or group of the migration task.
Basic examples
drush migrate:rollback migration_id
drush migrate:rollback --tag='Drupal 7'
drush migrate:rollback --group=files
migrate:stop (mst)
Included in Drush since 10.4.0. Use this to stop an active migration operation.
Basic example
drush migrate:stop migration_id
migrate:reset-status (mrs)
Included in Drush since 10.4.0. Use this to reset an active migration status back to idle.
Basic example
drush migrate:reset-status migration_id
migrate-manifest (no alias)
Provided by the Migrate Manifest module.
migrate:messages (mmsg)
Included in Drush since 10.4.0. Use this to view any messages associated with a migration. This is useful to use when you have a failure in your migration process. This will show you why they failed and what caused them.
Basic example
drush migrate:messages migration_id
migrate:fields-source (mfs)
Included in Drush since 10.4.0. Use this to list the fields available for mapping in a source.
Basic example
drush migrate:fields-source migration_id
migrate:tree (no alias)
Provided by Migrate Tools module, the only command not yet included in Drush. Use this to show a tree of migration dependencies.
Basic example
drush migrate:tree --tag='Drupal 7'
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