Wadslog

WordPressをMT(Movable Type)形式でエクスポートしてブログをお引越し。

Jul 17, 2009

wordpressで書いていたブログを、はてなに引っ越すことにしました。
結局こっちへ戻ってきました

実際に引っ越しを行ったバージョンはwordpress2.6です。

目次

インポート方法

はてなで既存ブログデータをインポートするには、Movable Type形式(MT形式)でデータをエクスポートする必要があります。

今使用しているwordpressのバージョンは2.6で、MT形式でデータをエクスポートするために、WordPressExportというプラグインを使用しました。

プラグインのインストール

インストール方法などはこちらをご覧ください

プラグインのインストール後、管理画面の「設定」タブから「Export」をクリックすると、MT形式でデータ表示されるはずでしたが、何も出てきませんでした。

プラグインの修正

調べてみると、MT.php内21行目付近の、SQLを発行している部分で、エラーがでていることがわかりました。

MT.phpの21行目付近

$query = "SELECT $wpdb->posts.post\_date, $wpdb->posts.post\_content, $wpdb->posts.post\_title, $wpdb->users.user\_nickname, $wpdb->posts.post\_status, $wpdb->comments.comment\_author,  $wpdb->comments.comment\_content, $wpdb->comments.comment\_author\_email,  $wpdb->comments.comment\_author\_url,  $wpdb->comments.comment\_date,  $wpdb->post2cat.category\_id, $wpdb->categories.cat\_name FROM $wpdb->comments RIGHT  OUTER  JOIN  $wpdb->posts  ON (  $wpdb->comments.comment\_post\_ID  =  $wpdb->posts.ID  ) LEFT  OUTER  JOIN  $wpdb->users  ON (  $wpdb->posts.post\_author  =  $wpdb->users.ID  ) LEFT OUTER  JOIN  $wpdb->post2cat  ON (  $wpdb->posts.ID  =  $wpdb->post2cat.post\_id ) LEFT OUTER JOIN $wpdb->categories ON ($wpdb->post2cat.category\_id = $wpdb->categories.cat\_ID) ";

また、エラーがでている部分はeval()関数で実行されていたので、特にエラーなど出現せず、単に出力がない状態となっていたのです。

SQLをダンプすると以下のようになっていました。

SELECT
  wp\_posts.post\_date,
  wp\_posts.post\_content,
  wp\_posts.post\_title,
  wp\_users.user\_nicename,
  wp\_posts.post\_status,
  wp\_comments.comment\_author,
  wp\_comments.comment\_content,
  wp\_comments.comment\_author\_email,
  wp\_comments.comment\_author\_url,
  wp\_comments.comment\_date,
  wp\_post2cat.category\_id,
  wp\_categories.cat\_name
FROM
  wp\_comments
RIGHT  OUTER  JOIN
  wp\_posts
ON (
  wp\_comments.comment\_post\_ID  =  wp\_posts.ID
)
LEFT  OUTER  JOIN
  wp\_users
ON (
  wp\_posts.post\_author  =  wp\_users.ID
)
LEFT OUTER  JOIN
  wp\_post2cat
ON (
  wp\_posts.ID  =  wp\_post2cat.post\_id
)
LEFT OUTER JOIN
  wp\_categories
ON (
  wp\_post2cat.category\_id = wp\_categories.cat\_ID
) 

このSQLでは、wp_categoriesと、wp_post2catというテーブルが見つからないためにエラーが発生しています。

いま使っているwordpress2.6では、これらのテーブルはありませんでした。 ただ、古いバージョンにはあったようなので、どこかのアップデートの段階でなくなったのだと思います。

プラグインが古くて、バージョンアップに対応していなかったのでしょうかね。

ということで、wp_categoriesとwp_post2catテーブル関連部分(SELECTとJOINのところ)、およびデータの書き出し部分で関係しているところを削除しました。

結果、SQLの部分は以下のようになりました。

$query = "SELECT $wpdb->posts.post\_date, $wpdb->posts.post\_content, $wpdb->posts.post\_title, $wpdb->users.user\_nicename, $wpdb->posts.post\_status, $wpdb->comments.comment\_author,  $wpdb->comments.comment\_content, $wpdb->comments.comment\_author\_email,  $wpdb->comments.comment\_author\_url,  $wpdb->comments.comment\_date  FROM $wpdb->comments RIGHT  OUTER  JOIN  $wpdb->posts  ON (  $wpdb->comments.comment\_post\_ID  =  $wpdb->posts.ID  ) LEFT  OUTER  JOIN  $wpdb->users  ON (  $wpdb->posts.post\_author  =  $wpdb->users.ID  ) ";

さて、修正して再度エクスポートをしてみたのですが、まだ何もでてきませんでした。次に怪しい部分は、23行目あたりからの、実際にクエリを投げてデータを取得する部分です。

MT.phpの23行目付近

$result = $wpdb->query($query);
if ($result){
    for ($i = 0; $i < $result; $i++) {
	    $row = $wpdb->get\_row(null,OBJECT,$i);

        if ($prev\_entry == $row->post\_date) {
            ...

$wpdp->query()でデータを取得して、$resultに取得した行数が代入されます。その回数分for文でまわして$wpdb->get_row()で一行づつ処理しようとしているのだと思います。

しかし、$wpdb->get_row()も途中で実装が変わったのか、第一引数にnullが指定されてしまうと、nullしかかえって来ません。

wp-includes/wp-db.php 733行目付近

function get\_row($query = null, $output = OBJECT, $y = 0) {
    $this->func\_call = "$db->get\_row("$query",$output,$y)";
    if ( $query )
        $this->query($query);
    else
        return null;

    if ( !isset($this->last\_result\[$y\]) )
        return null;

    if ( $output == OBJECT ) {
        return $this->last\_result\[$y\] ? $this->last\_result\[$y\] : null;
    } elseif ( $output == ARRAY\_A ) {
        ...

ここでは、nullのかわりにSQL文を指定するのが正しい使用方法です。

ただ、$wpdb->get_row()は本当に一行だけ取得したい場合に使用するべきです。 なぜなら、$wpdb->get_row()は内部で$wpdb->query()を呼び出しているので、毎回クエリが発生してしまうので効率が悪いためです。

今回のように一度にデータを取得して、結果をfor文で逐次処理を行う場合には、$wpdb->get_result()という関数が用意されています。

上記を踏まえ、以下のように処理を変更しました。

 //$result = $wpdb->query($query);
    $result = $wpdb->get\_results($query, OBJECT);
    if ($result){
		//for ($i = 0; $i < $result; $i++) {
		foreach($result as $i=>$row) {
			//$row = $wpdb->get\_row(null,OBJECT,$i);
			if ($prev\_entry == $row->post\_date) {
			...

このほかに、こちらにでも書いてありますが、エントリーの区切りが

\--------
--------

になってしまう件についても、

\-----
--------

```になるように修正しました。

MT.php 73行目付近

//$output .= “——–n”; $output .= “—–n”;


これでようやくMT形式でエクスポートできました。

ただし、ドラフト版もひとつのエントリーとして出力されてしまい、はてなではこれらもひとつの記事として公開されていて、具合が悪いです。

ということで、公開記事だけエクスポートされるように、wp\_posts.post\_status = 'publish'という条件をSQL文に付け加えました。

$query = “SELECT $wpdb->posts.post_date, $wpdb->posts.post_content, $wpdb->posts.post_title, $wpdb->users.user_nicename, $wpdb->posts.post_status, $wpdb->comments.comment_author, $wpdb->comments.comment_content, $wpdb->comments.comment_author_email, $wpdb->comments.comment_author_url, $wpdb->comments.comment_date FROM $wpdb->comments RIGHT OUTER JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID ) LEFT OUTER JOIN $wpdb->users ON ( $wpdb->posts.post_author = $wpdb->users.ID ) WHERE $wpdb->posts.post_status “;


これで、公開されたバージョンのみインポートすることができました(手作業で修正しなければならないことがちょっと残っていますが...)。

修正したWordPressExportプラグインのMT.phpは[こちらから](http://wadslab.net/wiki/index.php?WordPress%2Fplugin%2FWordPressExport%BD%A4%C0%B5%C8%C7)ダウンロードできます。

### 参考

*   [こんなエラーが出たら Table ‘wordpress.wp\_post2cat’ doesn’t exist for query - HWPS!](http://holy.enyou.org/2009/06/15/update-wordpress)
*   [WordPressのデータをMT形式でエクスポートする方法でつまづいた](http://d.hatena.ne.jp/yespamaster/20090409)
comments powered by Disqus