I’ve been working on migrating a fairly large site from Drupal to WordPress (actually WP is just a middle ground, it’s moving from there to another platform) and noticed a lack of decent information about Drupal to WP migration. Since I had to put some time in cleaning up MySQL scripts, and working through the move, I thought it’d be a good idea to document the information for anyone who needs to make the migration in the future.
First off, the original Drupal site is at version 6.22 and I’m migrating into WP 3.4.2.
Initial steps:
- Get MySQL access to the Drupal site, either command line via SSH or PhpMyAdmin.
- Grab a full dump of the DB (yes, you may not need the whole thing, but this way you know you’ve got all the info you might need). The Drupal db backup module in my case was incapable of backing up this db.
- Create a new database on the system you will use for migration and call it “drupal” – in my case I am working locally on my Xampp MySQL db.
- Import the db dump into your new database from the command line. Don’t waste your time trying to use PhpMyAdmin if you’ve got a decent size backup (mine was over 3 gigs). mysql -u username -p drupal < drupal.sql is the syntax (replace username with your mysql username and be prepared to be asked for the db password). The import may take a few minutes for a large database. (*note: if you are having trouble getting the import to work, you likely have mysql buffer sizes set too low. I found this to be the case with the XAMPP install of mysql, but I easily fixed it by editing my.ini via the XAMPP control panel. I think the innodb_buffer_pool_size setting was the one that did it, but most of the buffers were upped substantially. You can safely up innodb_buffer_pool_size to about 50% of your system memory.
- So now you’ve got your own import of the Drupal database. Go ahead and create your new WP database if you haven’t already and do your WP install.
Now we’re ready to start migrating data. First off, I import categories, but I need to warn you: WP requires unique category names, and apparently Drupal apparently does not. You will most likely need to make sure that you don’t have Drupal Term_Data entries with names that are similar, ie, Immigration and immigration. Change the names to something unique, like changing immigration to immigration issues and it will work.. Thus, you need to make sure that all the Category names are unique.
This script which I have slightly modified from the original from Lincoln Hawks at SocialCmsBuzz.com did the trick. I have also added user import, which wasn’t in the original. My WP database name is wptest and the drupal db is named as noted before “drupal”.
TRUNCATE TABLE wptest.wp_comments;
TRUNCATE TABLE wptest.wp_links;
TRUNCATE TABLE wptest.wp_postmeta;
TRUNCATE TABLE wptest.wp_posts;
TRUNCATE TABLE wptest.wp_term_relationships;
TRUNCATE TABLE wptest.wp_term_taxonomy;
TRUNCATE TABLE wptest.wp_terms;INSERT INTO wptest.wp_terms (term_id, `name`, slug, term_group)
SELECT
d.tid, d.name, REPLACE(LOWER(d.name), ‘ ‘, ‘-’), 0
FROM drupal.term_data d
INNER JOIN drupal.term_hierarchy h
USING(tid)
;INSERT INTO wptest.wp_term_taxonomy (term_id, taxonomy, description, parent)
SELECT
d.tid `term_id`,
‘category’ `taxonomy`,
d.description `description`,
h.parent `parent`
FROM drupal.term_data d
INNER JOIN drupal.term_hierarchy h
USING(tid)
;INSERT INTO
wptest.wp_posts (id, post_date, post_content, post_title,
post_excerpt, post_name, post_modified)
SELECT DISTINCT
n.nid, FROM_UNIXTIME(created), body, n.title,
teaser,
REPLACE(REPLACE(REPLACE(REPLACE(LOWER(n.title),’ ‘, ‘-’),’.', ‘-’),’,', ‘-’),’+', ‘-’),
FROM_UNIXTIME(changed)
FROM drupal.node n, drupal.node_revisions r
WHERE n.vid = r.vidINSERT INTO wptest.wp_term_relationships (object_id, term_taxonomy_id)
SELECT nid, tid FROM drupal.term_node;
UPDATE wp_term_taxonomy tt
SET `count` = (
SELECT COUNT(tr.object_id)
FROM wp_term_relationships tr
WHERE tr.term_taxonomy_id = tt.term_taxonomy_id
);INSERT INTO wptest.wp_comments (comment_post_ID, comment_date, comment_content, comment_parent, comment_author, comment_author_email, comment_author_url, comment_approved)
SELECT nid, FROM_UNIXTIME(timestamp), comment, thread, name, mail, homepage, status FROM drupal.comments;
UPDATE `wp_posts` SET `comment_count` = (SELECT COUNT(`comment_post_id`) FROM `wp_comments` WHERE `wp_posts`.`id` = `wp_comments`.`comment_post_id`);
UPDATE wptest.wp_posts SET post_content = REPLACE(post_content, ”, ”);
UPDATE wptest.wp_posts SET post_content = REPLACE(post_content, ‘”/sites/default/files/’, ‘”/wp-content/uploads/’);
INSERT IGNORE INTO wptest.wp_users SELECT NULL AS ID, NAME AS user_login, SUBSTRING(MD5(RAND()) FROM 1 FOR 30) AS user_pass, NAME AS user_nicename, mail AS user_email, ” AS user_url, FROM_UNIXTIME(created) AS user_registered, ” AS user_activation_key, 0 AS user_status, NAME AS display_name FROM drupal.users;UPDATE wptest.wp_posts JOIN drupal.node ON title = post_title JOIN drupal.users ON drupal.users.uid = drupal.node.uid JOIN wptest.wp_users ON drupal.users.name = wptest.wp_users.user_nicename SET wptest.wp_posts.post_author = wptest.wp_users.ID
One note for you: I found the line where we updated our content image links didn’t really take care of what I needed. My Drupal db was full of absolute links for image sources so I ended up having to change each by doing something like: UPDATE wptest.wp_posts SET post_content = REPLACE(post_content, ‘my.drupal.site/sites/default/files/’, ‘/wp-content/uploads/oldimages’); for each of the image urls. I then mass imported the images via ftp into my wp-content/uploads/oldimages/ directory. This meant they weren’t included in the WP media library as I would prefer, but at least the images were there.
Let me know if you’ve got improvements, especially if you write a script to import the images into the media library!


In the end, it wasn’t the Internet, or televsion or even bad management that killed journalism; we did it to ourselves.
My years at Namemedia ended last month and I’m no longer forced to commute to Waltham from Central MA anymore. While I miss everyone I worked with at Namemedia, I certainly do not miss the commute.
Aggressive Drivers Suck – newsflash: driving 90 weaving in and out when everyone else is doing 70 doesn’t get you there any faster. I generally pass clowns like you at the tolls. And no, that’s not a “you’re number one” signal everyone is giving you.
We are all a little less today, for the loss of a great newsman, Mike Wallace, formerly of 60 Minutes. He was a slave to the story; where it lead and who it lead to be damned.
I saw the video on the news the other night of these guys who’s boat sank and one was able to film the entire episode with his helmet cam. It was truly scary stuff for any boater, but for me, having been through the same ordeal, it was utterly terrifying.
We live at a critical juncture in history.
It’s been a long time since I posted. I’ve been wrapped up in endless development cycles, dealing with real world stuff and generally had way too much going on to have the time to deposit any gems of wisdom on you. Of course, that presupposes that at this point, I do. Which I do not…
15 months upgrading from Php 4 and Mysql4 to the latest versions. This was a project previous engineers had been tasked with. Some ran screaming out of the building. None seriously attempted it. For us it only happened because our Senior Architect Brian Kirsten was smart enough to know it was possible, and because I was too dumb to say “no way.”