latin1 で作ってしまったデータベースを phpMyAdmin で文字化けせずに export する方法

phpmyadmin_export.png
昨晩は EC-CUBEで構築された、とある EC サイトの移行作業であった。 フリーエンジニアの場合、夜中に作業出来ることを重宝されることがある。今回のような移行作業は特に。ようは、お買い物に来る人が少ない時間帯に移行作業をやってしまおうってやつだ。

昼間のうちに必要な情報はすべて集め、夜までは他の仕事をこなしつつ、約束していた移行作業の開始時間を待っていた。

「そういえば、MySQLのダンプを忘れていたなー。phpMyAdmin がインストールされているはず(今回の作業を引き受ける条件として、phpMyAdminがインストールされているサーバという話をしていたので)なんだけど、URLを聞くのを忘れていたなー」

ということでお客さんに電話した。

「えっと、管理画面とかそういうの無いんですよ。確認して折り返し電話します。」

という回答。嫌な予感。

結局、お客さんからレンタルサーバ屋さんに連絡してもらって、phpMyAdmin を急遽インストールしてもらった。なかなか親切なレンタルサーバ屋さんだ。と感心しながら、インストールしてもらった phpMyAdmin を使って、MySQL データベースのデータを export する。

ところが、見事に文字化けしているのである。なんか、さらに嫌な予感がしてきた。
もうお客さんは帰ってしまったし、そのレンタルサーバ業者もよく知らない。

phpmyadmin_latin1_swedish.png
nkf とか、iconv を駆使して文字化けを解消しようとするがうまくいかず。
phpMyAdmin の画面をよく見ると、latin1_swedish_ci とか書いてある 。iconv で確認してみると、

% iconv --from-code=utf8 --to-code=latin1 dumpfile
(一部省略)
, `welcome_point`, `update_date`, `top_tpl`, `product_tpl`, `detail_tpl`,
 `mypage_tpl`, `good_traded`, `message`, `regular_holiday_ids`) VALUES
('株式〓〓iconv: illegal input sequence at position 2625

やっぱりである。ようは、latin1 で作られたテーブルに、そのまま(UTF-8)のデータを登録しているのだが、phpMyAdmin が(UTF-8だとは知らずに) latin1 から UTF-8 への変換をしているのだ。

しかし、先ほど試したように、iconv での変換は無理なので(illegal input sequence のエラーになるので)、他の方法を探さねばならなかった。

Google で検索して見つかるのは、mysql_dumpコマンドを使った方法。しかし、このレンタルサーバ、おそらくシェルアカウントは準備していないだろうし、もし用意していたのだとしても連絡する方法も、アカウントもまったく知らない。

で、あきらめて phpMyAdmin にパッチを当てことにした。

先ほど、色々といじくっているときに調べたのだが、

SET NAMES latin1;
SELECT * FROM dtb_customer LIMIT 10;

などとすれば、文字化けせずにデータが取り出せることを確認した(phpMyAdmin は SQLコマンドを実行できる画面も準備しているのでそれで試した)。ということは、この export 処理の SQLの前に、上記のような「SET NAMES latin1」を実行してやれば良さそうだ。

で、当てたパッチがこれ。phpMyAdmin の最新版だと PHP 5.3 必須だったので、PHP5.2 でも使える phpMyAdmin-2.11.10 ってやつのソース。

*** libraries/export/sql.php~	2009-12-08 02:14:45.000000000 +0900
--- libraries/export/sql.php	2010-07-29 00:44:22.242317492 +0900
***************
*** 250,255 ****
--- 250,256 ----
                 . '/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;' . $crlf
                 . '/*!40101 SET NAMES ' . $set_names . ' */;' . $crlf . $crlf;
      }
+     PMA_DBI_query('SET NAMES latin1');
  
      return PMA_exportOutputHandler($head);
  }

こういうのって、勘が大事。自慢じゃないが、20年もこういう仕事やってるので、該当箇所はすぐにわかった(grep コマンド駆使して色々と探したけど)。たぶん、上記のパッチで良いと思う(僕のお客さんの環境だとうまくいった)。もっと良い場所があるかもしれないけど。まあ、急ぎだったのと(当然朝までに仕上げなければならない)、結果オーライで。あと、このやり方は無保証なので、問題あっても私は責任をとれません。もしあれやったら、お金かかりますがお仕事としてご依頼下さいね

添付サイズ
patch.phpMyAdmin-2.11.10.latin1_export.patch457 byte

どうでもいいことですが

phpMyAdmin は、インストールされていなくても自分でインストールすれば動く可能性が高いので、入ってなくても自分でインストールすればいいです。

実際、上記パッチを当てようとしたのですが、root 権限でインストールされていたために、パッチは当てられず、結局自分でインストールしたのでした。

新しいコメントの投稿

このフィールドの内容は非公開にされ、公表されることはありません。
  • HTMLタグは使用できません
  • 行と段落は自動的に折り返されます。

書式オプションに関するより詳しい情報...

CAPTCHA
この質問はあなたが人間であるかどうかについて調べる為と、自動化したスパムを防ぐ為のものです。うまくいかない場合は電子メールでお問い合わせ下さい。
イメージ CAPTCHA
画像の中に見える文字を入力して下さい