Drupal 7 Upgrade Advice: Data Migration

For all but the simplest of websites, a major version upgrade of Drupal is nothing short of daunting. More than likely, you're currently using modules that don't have stable 7.x releases, or perhaps there's no official upgrade path to the 7.x version. Expect to spend a decent chunk of time "massaging" data through the upgrade process.

We're only halfway through upgrading a very large Drupal 6 site (and I plan a full rundown or series when it's complete), but I have a few nuggets of wisdom that may be valuable to those about to embark on the same journey.

Lesson #1: Drupal may not be the best tool for the job.

As you're upgrading, you should keep this in mind: Drupal is a fantastic platform for creating and managing webpages (among other things), but that doesn't necessarily mean that Drupal is a fantastic platform to do anything else.

Possibly, there's a fantastic way to solve your data migration problem using Drupal: CCK's Content Migrate module works wonders for most fields, the Migrate module is a very pluggable system for this very issue, even outside of an upgrade context.

What qualifies as the "best" tool can depend on a number of factors, but ultimately boils down to only one thing: your personal familiarity with the tool at hand.

It might be perfectly valid to migrate data "the Drupal way" using the Migrate module, or perhaps writing a small module with a series of update functions, but if you're unfamiliar with both of those, and especially if you're on a tight deadline, use something else that you already know well.

Case in Point: Moving from Profile Fields to Profile2

You may already be familiar with this article, which demonstrates how to do this using the Migrate module. However, there are a number of dependencies that I didn't want to bother investigating (namely, Migrate Extras, and another migration "grasmashUser).

The solution that I devised, using what I was already familiar with, was to simply export the Profile 2 profile I'd made in Drupal 7 (and all of its fields) as a Feature. During the upgrade process, I enable the feature, which creates the fields and all requisite tables, then perform a series of simple SQL commands (in the form of INSERT … SELECT) to move the data into the right tables.

INSERT INTO field_data_field_profile_first_name (entity_type, bundle, deleted, entity_id, revision_id, language, delta, field_profile_first_name_value)
SELECT 'profile2', 'about_you', 0, p.pid, p.pid, 'und', 0, pv.value
FROM profile_value pv
LEFT JOIN profile p ON pv.uid=p.uid WHERE fid=1;
INSERT INTO field_revision_field_profile_first_name (entity_type, bundle, deleted, entity_id, revision_id, language, delta, field_profile_first_name_value)
SELECT 'profile2', 'about_you', 0, p.pid, p.pid, 'und', 0, pv.value
FROM profile_value pv
LEFT JOIN profile p ON pv.uid=p.uid WHERE fid=1

Automating the above can be done very easily using two commands: drush en and drush sqlq.

The same queries above can be adapted for different profile fields by simply changing the fid (corresponding to D6 Profile Field's field IDs) in the WHERE clause as well as the table name (corresponding to D7 Field data and revision tables) in the insert statements.

It's not the most "Drupal" way to do it, but it gets the job done.