3 Simple Fixes and Workarounds for Drupal 7 to Drupal 8 Migrations

Jaime Contreras
Jaime ContrerasSenior Web Developer
Simple Fixes and Workarounds for Drupal 7 to Drupal 8 Migrations

There are a lot of migration articles online that explain how to edit YAML configurations and custom migration plugins, so I am skipping over that.

You should be familiar with the full migration concepts first.  But before you start the migration process, you will need to clean up a few things from the old D7 site as well as prepare the new D8 site to make it able to take the old data including installing new modules for specific field types. That is what this article is about.

By cleaning up data before and after migration things will go more smoothly, minimizing the need to write complicated YAML or PHP scripts.

IMPORTANT NOTE: Do not work directly from the live D7 site. It’s best to backup and export your D7 database to a new database first. This way you will be able to clean up the database content with a few SQL commands.

Now for the workarounds... including some helper SQL commands I use when doing a Drupal 7 to Drupal 8 migration.

1. The annoying “value cannot be NULL errors” in body_value on import.

This can happen in any field, but for this example, I will use the “body_value” column in the “body__value” table. For the sake of this example, this field is required by the default body field in D8.

In the old D7 database, “body_value” sometimes may be NULL. The simple fix, if you can get away with it, is specifying a default value. Maybe it can be a special string that you can go back after the migration and search with a simple SQL query to find all the missing values so that you can replace with actual content.

Option 2 is to copy content that can be used from another field or column.

In my latest migration, the “body_value” column was NULL in a large number of records, but I did have a value I could use in the “body_summary” column in every single record.

The quick easy fix is to run this query in the D7 database. In my case, it fixed 400+ records not only making the import smooth, but also correcting the storage of the content.

UPDATE field_data_body SET body_value = body_summary WHERE body_value='' AND bundle='>>REPLACE WITH YOUR BUNDLE TYPE<<';

If you just want to set the value to some default value, you can.

UPDATE field_data_body SET body_value = '>>REPLACE WITH SOME DEFAULT VALUE<<' WHERE body_value='' AND bundle='>>REPLACE WITH YOUR BUNDLE TYPE<<';

Here is another useful one if the D7 site was in English only. It will set all the records to have en(English) as default language instead of und(undefined).

UPDATE field_data_body SET `language`='en' WHERE `language`='und'

2. Importing Redirects issues to the new site.

In my experience, Redirects import without much of problem and do not make adjustments to the YAML file. However, I did notice that the Redirects status came in wrong. Redirects status code cannot be “0” or NULL in Drupal 8 so you have to default it to 301 (moved permanently) or any other acceptable HTML redirect code you prefer. Again you can edit the YAML or, for easy quick clean up, just run this code:

Run this on the D7 database before import:

UPDATE redirect SET status_code=301 WHERE status_code=0;
UPDATE redirect SET status_code=301 WHERE status_code IS NULL;

Or, run this on the D8 database after import:

UPDATE redirect SET status_code=301 WHERE status_code IS NULL;

3. Importing URL Aliases from Drupal 7 to Drupal 8 is easy.

Ok, this requires a little more work than just running a SQL command, but I promise it will save you a lot of headaches as opposed to doing the Drupal migration because the aliases may create all kinds of problems.

I found that the easiest way is to simply export the “url_alias” table from the old site and import it replacing the new Drupal 8 database “url_alias” table. The replacement of the aliases in the new D8 site is to be done as a final stage of migration. Once you have completed the full migration of your content, nodes, entities, taxonomies, configurations, etc., you have tested that all the content has migrated successfully and you are ready to wrap it all up. Then follow these steps:

First, if you are using “Pathauto”, make sure you have the module installed and the URL alias patterns to match those from the D7. Pathauto configuration is at: /admin/config/search/path/patterns

Delete the D8 database “url_alias” table so that you can replace it with the new table and run this command in the D8 database: (You may want to back up this table before deleting all of the URL aliases)

DROP TABLE url_alias;

Export the table “url_alias” from the D7 database and import into the new D8 database using your preferred database management application.

Fix the URLs so that it works with D8 and run this SQL commands on the D8 database:

UPDATE url_alias SET url_alias.source = concat("/",url_alias.source);
UPDATE url_alias SET url_alias.alias = concat("/",url_alias.alias);

Now let’s change the name of the “language” column to “lancode” in the D8 database:

ALTER TABLE url_alias CHANGE language langcode varchar(12);

Now, if you are using Pathauto, let’s auto regenerate any missing aliases: Check all the types of aliases to regenerate all. And make sure that the “Generate a URL alias for un-aliased paths only” is checked so that it doesn’t overwrite all the aliases we just imported, and let it run. (You may notice that it may only create a few, if any. That’s okay because if we did the job right, all the alias should already be created) /admin/config/search/path/update_bulk

Check and test that all your aliases are working.

In conclusion, if you take the time to clean up your data before the migration, things will be a lot easier. Also, if later you need to pull an updated database from the old site, saving all your SQL commands and tracking your process, you will be able to clean up a fresh database in no time for re-import.