DrupalからWordPressに引っ越し

長年使ってきたDrupal 7をWordpressに引っ越すことにした。

まずは、Drupalのデータベースを調査する。
「タイトル」と「ボディ」と「更新日」がそれぞれ別テーブルで保存されている。つまり、1ページのHTMLが複数のテーブルでバラバラに保存されている。これでは引っ越ししにくい。よってidを使って1ページ分を1行のデータで書き出せたら楽にWordpressに移行できる。。。
テーブルに何が保存されているか調べるところから始めた。

テーブルに何が保存されているか調べる

[block]テーブル    534件    「タイトル」が保存されている。

mysql> show columns from block;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| module     | varchar(64)  | NO   |     |         |                |
| delta      | varchar(32)  | NO   |     | 0       |                |
| status     | tinyint(2)   | NO   |     | 0       |                |
| weight     | int(11)      | NO   |     | 0       |                |
| region     | varchar(64)  | NO   |     |         |                |
| custom     | tinyint(2)   | NO   |     | 0       |                |
| visibility | tinyint(1)   | NO   |     | 0       |                |
| pages      | text         | NO   |     | NULL    |                |
| theme      | varchar(64)  | NO   | MUL |         |                |
| title      | varchar(255) | NO   |     |         |                |
| bid        | int(11)      | NO   | PRI | NULL    | auto_increment |
| cache      | tinyint(4)   | NO   |     | 1       |                |
+------------+--------------+------+-----+---------+----------------+

内容を確認する。
select bid, title, weight, status, module, region from block;

[field_data_body] 505件 「ボディ」が保存されている。
[field_data_body]bundle = story または page または book が保存されている。

mysql> show columns from field_data_body;
+--------------+------------------+------+-----+---------+-------+
| Field        | Type             | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| entity_type  | varchar(128)     | NO   | PRI |         |       |
| bundle       | varchar(128)     | NO   | MUL |         |       |
| deleted      | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id    | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id  | int(10) unsigned | YES  | MUL | NULL    |       |
| language     | varchar(32)      | NO   | PRI |         |       |
| delta        | int(10) unsigned | NO   | PRI | NULL    |       |
| body_value   | longtext         | YES  |     | NULL    |       |
| body_summary | longtext         | YES  |     | NULL    |       |
| body_format  | varchar(255)     | YES  | MUL | NULL    |       |
+--------------+------------------+------+-----+---------+-------+

内容を確認する。
select entity_id, revision_id, bundle, entity_type, body_value from field_data_body order by entity_id;

[node]    506件    「タイトル」が保存されている。

mysql> show columns from node;
+-----------+------------------+------+-----+---------+----------------+
| Field     | Type             | Null | Key | Default | Extra          |
+-----------+------------------+------+-----+---------+----------------+
| nid       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| type      | varchar(32)      | NO   | MUL |         |                |
| title     | varchar(255)     | NO   | MUL |         |                |
| uid       | int(10)          | NO   | MUL | 0       |                |
| status    | int(4)           | NO   | MUL | 1       |                |
| created   | int(11)          | NO   | MUL | 0       |                |
| changed   | int(11)          | NO   | MUL | 0       |                |
| comment   | int(2)           | NO   |     | 0       |                |
| promote   | int(2)           | NO   | MUL | 0       |                |
| sticky    | int(2)           | NO   |     | 0       |                |
| vid       | int(10) unsigned | YES  | UNI | NULL    |                |
| language  | varchar(12)      | NO   | MUL |         |                |
| tnid      | int(10) unsigned | NO   | MUL | 0       |                |
| translate | int(11)          | NO   | MUL | 0       |                |
+-----------+------------------+------+-----+---------+----------------+

内容を確認する。
select nid, type, title, from_unixtime(created), from_unixtime(changed) from node order by nid;

[url_alias]    406件    「URL」が保存されている。

mysql> show columns from url_alias;
+----------+------------------+------+-----+---------+----------------+
| Field    | Type             | Null | Key | Default | Extra          |
+----------+------------------+------+-----+---------+----------------+
| pid      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| source   | varchar(255)     | NO   | MUL |         |                |
| alias    | varchar(255)     | NO   | MUL |         |                |
| language | varchar(12)      | NO   |     |         |                |
+----------+------------------+------+-----+---------+----------------+

tsv ダウンロード 1

ボディ部分とタイトル部分をとりあえずtsvで取得してみた。

ボディ
% mysql -h mysql0000.db.sakura.ne.jp -uNAME -p -e "select entity_id, revision_id, bundle, entity_type, body_value from field_data_body order by entity_id" my_drupal7 > body.tsv


タイトル
% mysql -h mysql0000.db.sakura.ne.jp -uNAME -p -e "select nid, type, title, from_unixtime(created), from_unixtime(changed) from node order by nid" my_drupal7 > title.tsv

tsv ダウンロード 2

次のステップ。内部結合で取得してみた。

[node]    506件    タイトル
[field_data_body]    505件    ボディ



件数を確認する。 505件
SELECT count(*) FROM node INNER JOIN field_data_body ON node.nid = field_data_body.entity_id;


ボディのフィールドを追加する
SELECT nid, type, title, from_unixtime(created), from_unixtime(changed), field_data_body.bundle, field_data_body.entity_type, field_data_body.body_value FROM node INNER JOIN field_data_body ON node.nid = field_data_body.entity_id ORDER BY nid;


ダウンロード
% mysql -h mysql0000.db.sakura.ne.jp -uNAME -p -e "SELECT nid, type, title, from_unixtime(created), from_unixtime(changed), field_data_body.bundle, field_data_body.entity_type, field_data_body.body_value FROM node INNER JOIN field_data_body ON node.nid = field_data_body.entity_id ORDER BY nid" my_drupal7 > title_body.tsv


ダウンロード 日付改善
% mysql -h mysql0000.db.sakura.ne.jp -uNAME -p -e "SELECT nid, type, title, from_unixtime(created), date_sub(from_unixtime(created), INTERVAL 9 HOUR), from_unixtime(changed), date_sub(from_unixtime(changed), INTERVAL 9 HOUR), field_data_body.bundle, field_data_body.entity_type, field_data_body.body_value FROM node INNER JOIN field_data_body ON node.nid = field_data_body.entity_id ORDER BY nid" mmy_drupal7 > title_body.tsv

日付問題への対処

日本時間に対処するため、9時間ほど引き算するテストのメモ。

実験
mysql> select from_unixtime(created), addtime(from_unixtime(created), '0 9:0:0') from node;


作成日 -9h
mysql> select from_unixtime(created), date_sub(from_unixtime(created), INTERVAL 9 HOUR) from node;


更新日 -9h
mysql> select from_unixtime(changed), date_sub(from_unixtime(changed), INTERVAL 9 HOUR) from node;

WordPress で砂場作成

テスト環境(お砂場)を作成する。

% mysql -h mysql0000.db.sakura.ne.jp -u NAME -p


mysql> use my_wp1


■空テーブル wp_posts2 を作成する
mysql> create table wp_posts2 like wp_posts;



■データをコピーする
mysql> insert into wp_posts2 select * from wp_posts;


テスト用テーブル test 作成
mysql> CREATE TABLE test (name char(20) CHARACTER SET utf8mb4);


tsvインポートの実験


特定列だけをインポートする
LOAD DATA LOCAL INFILE "/home/name/test.tsv"
INTO TABLE test
(@1, @2, @3)
SET name=@1;


エラーが発生する
ERROR 1148 (42000): The used command is not allowed with this MySQL version


--local_infile=1 を付けてmysqlにログインする。
% mysql -h mysql0000.db.sakura.ne.jp -u NAME -p --local_infile=1


my.cnfに追加しておく。
loose-local-infile=1


mysql> LOAD DATA LOCAL INFILE "/home/name/test.tsv"
    -> INTO TABLE test
    -> (@1)
    -> SET name=@1;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0


mysql> select * from test;
+------+
| name |
+------+
| aaa  |
|      |
| aaa  |
|      |
+------+
4 rows in set (0.00 sec)



wpでの実験
LOAD DATA LOCAL INFILE "/home/name/test.tsv"
INTO TABLE wp_posts2
(@1, @2, @3)
SET post_name=@1;


お尻に2行追加されたことを確認。

wpでの実験2
mysql> use my_wp1;
mysql> truncate table wp_posts2;
mysql> LOAD DATA LOCAL INFILE "/home/name/title_body.tsv"
INTO TABLE wp_posts2
IGNORE 1 LINES
(@1, @2, @3, @4, @5, @6, @7, @8, @9, @10)
SET 
ID=@1,
post_author=1,
post_date=@4,
post_date_gmt=@5,
post_content=@10,
post_title=@3,
comment_status='closed',
post_modified=@6,
post_modified_gmt=@7
;

本番実施

テストが上手く行ったので本番を実施する。

mysql> use my_wp1


バックアップを実施する。
mysql> truncate table wp_posts2;
mysql> insert into wp_posts2 select * from wp_posts;


コンテンツを空にする。
mysql> truncate table wp_posts;


インポートする。
mysql> LOAD DATA LOCAL INFILE "/home/name/title_body.tsv"
INTO TABLE wp_posts
IGNORE 1 LINES
(@1, @2, @3, @4, @5, @6, @7, @8, @9, @10)
SET
ID=@1,
post_author=1,
post_date=@4,
post_date_gmt=@5,
post_content=@10,
post_title=@3,
comment_status='closed',
post_modified=@6,
post_modified_gmt=@7
;


無事にインポート完了。