Series Overview & ToC | Previous Article | Next Article


As pointed out in the first article, the Migrate API scope is to move over content and configuration. Porting modules and themes are out of scope. With that in mind, let’s take a closer look at some of the assumptions and limitations. In addition to what will be presented in today’s article, I highly recommend reviewing the official documentation for upgrading from Drupal 7. Drupal is ever-evolving and the Migrate API documentation gets updated regularly. Of particular importance, review the page on known issues when upgrading from Drupal 7, as things get added and removed from that list as issues are discovered and fixed.

Stay up to date

The first assumption is that your Drupal 7 site is fully up to date. That is, Drupal core itself and any contributed module or theme should be in the latest available versions. Over the years, I have seen projects delay updates unless they are security-related. And, when many updates accumulated, they were skipped out of concern that changes could break existing functionality. I have also seen projects skip new releases altogether because everything was working, so there was no perceived reason to implement changes.

Running old versions of Drupal core or contributed modules and themes is not a good idea. If a new security release is available, it is safer and faster to apply the update if you are already on the latest stable version. You also get the benefits of new features and bug fixes.

To illustrate the importance of having your Drupal 7 site up to date, let’s consider the Geofield module. The latest stable version in the 8.x branch is compatible with Drupal 10 and provides an automated upgrade path for the Geofield module in Drupal 7; specifically, the 7.x-2.x branch. I once worked on a project that used the 7.x-1.x branch in their Drupal 7 site. The automatic migration was failing because the field schema between the two Drupal 7 branches was different. The version compatible with Drupal 10 assumed you were using the latest release for Drupal 7. In this case, a custom migration was needed to migrate the data.

The same assumption applies for Drupal 10. Make sure you are on the latest stable version of Drupal core and any contributed module and theme you plan on using. It is common for migration projects to take months to complete, so make sure to apply updates as they become available during the lifespan of the project. When new releases are available, be sure to read the release notes for anything that might affect the migration and make changes as necessary. Also, stay current with Drupal’s change records, as they might highlight modifications that impact the migration system. For instance, Drupal 10.1 introduced a new password hashing algorithm. In this case, sites upgrading from Drupal 7 need to enable a new Password Compatibility module so that old passwords continue to work. Note that contributed modules like Migrate Plus and Migrate Tools also publish change records.

Enable modules on the source and destination sites to attempt an automated migration

As part of the migration from Drupal 7 to Drupal 10, the system checks for which modules are enabled on both sites. From the list of enabled modules in Drupal 10, the system checks which ones provide an automated upgrade path from Drupal 7. In many cases, having the same module enabled on both sites is enough for the corresponding data to be migrated. Examples of this are the core Node and User modules and the contributed Pathauto and Redirect modules.

Drupal 10 availability does not guarantee an automated upgrade path. For example, the core Views module in Drupal 10 does not provide an upgrade path from the contributed Views module in Drupal 7. For migrating Views, the Views migration module goes a long way in automating the process. Similarly, the Webform module is available for both Drupal 7 and Drupal 10, but there is no automated upgrade path. The Webform migrate module can be used to port webform data.

It is also possible that a Drupal 7 module is no longer available in Drupal 10, but a new module offers similar functionality and an upgrade path. For example, the Address Field module for Drupal 7 was superseded by the Address module in Drupal 10. In this case, Address in Drupal 10 provides an automated upgrade path for data stores in Address Field in Drupal 7. Another example is the Paragraph module for Drupal 10, which provides an upgrade path for the Field collection module in Drupal 7. Also, the Profile 2 module for Drupal 7 was replaced by the Profile module in Drupal 10. At the time of writing, the automated migration of profiles requires applying a patch.

In certain instances, a Drupal 7 module is replaced by a different module in Drupal 10, but no automatic upgrade path is provided. In those cases, a third module can be used to bridge the gap and automate the migration. For instance, the Nodequeue module in Drupal 7 was superseded by the Entityqueue module in Drupal 10. Here, the Nodequeue migrate module can be used to move the data over. At the time of writing, there is an open issue to add Drupal 10 compatibility to this module. Another example is the Migrate URL2Link module that provides an upgrade path from the contributed URL field module in Drupal 7 to the core Link module in Drupal 10.

Drupal modules can contain sub-modules, like the Webform module. It is possible that the automated upgrade path to Drupal 10 was separated into a sub-module that needs to be enabled separately. This is the case for the Field Group module, which is available for both Drupal 7 and in Drupal 10. To move field group data, in addition to the primary Field Group module for Drupal 10, it is necessary to enable the Field Group Migrate sub-module.

Also, modules in Drupal 7 could have been refactored and broken into multiple projects in Drupal 10. For example, in Drupal 7, there was a single core Block module. In Drupal 10, block functionality was broken into two modules: Block and Block Content modules. The former handles block configuration entities while the latter takes care of block content entities. To properly get block data migrated from Drupal 7, you need both modules enabled in Drupal 10.

Do not create any content or configuration in the destination site

By default, the automated upgrade procedure will attempt to create a verbatim copy of the legacy site. That is, Drupal 10 will try to recreate all configuration and content present in Drupal 7. In order to do this, the assumption is that Drupal 10 is installed with the minimal installation profile, followed by the upgrade procedure. It is important to manage expectations throughout the upgrade process. Unless there are automated upgrade paths for all modules used in Drupal 7, it is likely that there will be parts of the site that will not be ported automatically. Also, as discussed in the first article, only content and configuration will be moved by the Migrate API. Porting custom modules or themes is a separate task.

To understand this assumption, let’s consider what the Migrate API does under the hood. In terms of configuration, it will try to recreate all content types, fields, vocabularies, user roles, view modes, etc. Configuration already present on the site will be overwritten if the Drupal 10 identifier matches the one from Drupal 7. Be mindful that an installation profile can create configuration. For example, the standard installation profile in Drupal 10 creates the Article and Basic page content types, the Tags vocabulary, several fields, a comment type, a contact form, 3 text formats of which 2 use a WYSIWYG editor, 4 user roles, and more. If you were to run the automated migration on a Drupal 10 site that already had configuration, you might end up with seemingly repeated configuration; having two comments fields in a single content type, for instance. The recommendation is to install the site using the minimal installation profile, run the automated upgrade, and adjust the configuration afterward as needed.

With regard to content, the Migrate API will attempt to move all nodes, users, taxonomy terms, files, etc. Again, if the identifier of a Drupal 10 entity matches one from Drupal 7, it will be overwritten. This is very problematic because content entities tend to reference one another. For example, a node stores a reference to the user who created it. It can also hold references to files and taxonomy terms. If content is already present in the Drupal 10 site and it gets overwritten, those relationships will be lost or point to the wrong targets. To prevent data loss, the recommendation is to not create any content until the automated process is completed. There are workarounds to prevent ID conflicts that will be discussed in future articles.

As you can imagine, not being able to create content or configuration in the new Drupal 10 site is a big limitation. In fact, having a verbatim copy of the legacy Drupal 7 site is rarely the goal of a Drupal 10 migration project. As mentioned in the previous articles, it is common to change the site configuration and not migrate content that is no longer needed. As part of this series, we will teach you how to deviate from the recommendation to perform a custom migration. We will cover how to selectively use some of the configuration and content migrations and how to write custom ones when necessary.

Contact us to learn how we can help with your migration.


Image by Pexels from Pixabay