How to Migrate from Drupal 5.7 to Wordpress 2.8


This post came from Mike Smullin's post (Thanks Mike!). There is a bunch of similar posts out there, but I think they have several things in common: it depends on which version of Drupal/WP you use, what settings you've applied, etc. So, every script is just the same, it's you who have to add some minor changes according to your tables/database/host settings.

IMPORTANT: Always back up your data before run this script OR do it locally with experimental database. I'm not responsible for any single error you get. And feel free to give a comment or correction

# Original script from Mike Smullin

# Change wordpress_db to your Wordpress Database
# Change drupal_db to.. you guessed

# first, nuke previous content in wordpress database
TRUNCATE TABLE wordpress_db.wp_comments;
TRUNCATE TABLE wordpress_db.wp_links;
TRUNCATE TABLE wordpress_db.wp_postmeta;
TRUNCATE TABLE wordpress_db.wp_posts;
TRUNCATE TABLE wordpress_db.wp_term_relationships;
TRUNCATE TABLE wordpress_db.wp_term_taxonomy;
TRUNCATE TABLE wordpress_db.wp_terms;

# categories
INSERT INTO wordpress_db.wp_terms (term_id, `name`, slug, term_group)
d.tid,, REPLACE(LOWER(, ' ', '_'), 0
FROM drupal_db.term_data d
INNER JOIN drupal_db.term_hierarchy h

INSERT INTO wordpress_db.wp_term_taxonomy (term_id, taxonomy, description, parent)
d.tid `term_id`,
'category' `taxonomy`,
d.description `description`,
h.parent `parent`
FROM drupal_db.term_data d
INNER JOIN drupal_db.term_hierarchy h

# posts; keeping private posts hidden
INSERT INTO wordpress_db.wp_posts (id, post_date, post_content, post_title, post_excerpt, post_name, post_modified, post_type, `post_status`)
n.nid `id`,
FROM_UNIXTIME(n.created) `post_date`,
r.body `post_content`,
n.title `post_title`,
r.teaser `post_excerpt`,
IF(SUBSTR(a.dst, 11, 1) = '/', SUBSTR(a.dst FROM 9), a.dst) `post_name`,
FROM_UNIXTIME(n.changed) `post_modified`,
IF(n.type = 'story', 'post', IF(n.type = 'page', 'page', n.type)) `post_type`,
IF(n.status = 1, 'publish', 'private') `post_status`
FROM drupal_db.node n
INNER JOIN drupal_db.node_revisions r
LEFT OUTER JOIN drupal_db.url_alias a
ON a.src = CONCAT('node/', n.nid)
WHERE n.type IN ('story', 'page')

# post -> category relationships
INSERT INTO wordpress_db.wp_term_relationships (object_id, term_taxonomy_id)
SELECT nid, tid FROM drupal_db.term_node;

# category count updating
UPDATE wordpress_db.wp_term_taxonomy tt
SET `count` = (
SELECT COUNT(tr.object_id)
FROM wordpress_db.wp_term_relationships tr
WHERE tr.term_taxonomy_id = tt.term_taxonomy_id

# comments; keeping unapproved comments hidden
INSERT INTO wordpress_db.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 +1)%2) FROM drupal_db.comments;

# update comments count on wp_posts table
UPDATE wordpress_db.wp_posts SET `comment_count` = (SELECT COUNT(`comment_post_id`) FROM wordpress_db.wp_comments` WHERE wordpress_db.wp_posts.`id` = wordpress_db.wp_comments.`comment_post_id` AND wordpress_db.wp_comments.comment_approved = 1);

# fix breaks in post content
UPDATE wordpress_db.wp_posts SET post_content = REPLACE(post_content, '', '');
# fix images in post content
UPDATE wordpress_db.wp_posts SET post_content = REPLACE(post_content, '"/files/', '"/wp-content/uploads/');

When updating the posts table, it's quite tricky. If there is a '/' in the url alias, it's a 'story' with an alias like /2009/10/hello-word.html. The number 9 (nine) in line IF(SUBSTR(a.dst, 11, 1) = '/', SUBSTR(a.dst FROM 9), a.dst) `post_name`, shows that my alias is set to '/year/month/title.html' format. If you use '/year/month/date/title.html' format, make sure you change 9 to 11.

I'm using Drupal 5.7 and Wordpress 2.8.

3 komentar:

  1. UPDATE: comment_date_gmt has relationship to Comment RSS, so it's better to change the value based on gmt_offset in wp_options table

    UPDATE wp_comments SET comment_date_gmt = from_unixtime(unix_timestamp(comment_date) - ((select option_value from wp_options where option_name = 'gmt_offset' limit 1 )* 3600))

  2. err... It's gmt_date_offset. Sorry..

  3. Coba coba tes koneksi


speak now or forever hold your peace

About Me