2012年6月15日

"csvsql" を使って郵便番号データをデータベースに入れる

"csvkit" には csvsql というコマンドラインツールが付属しています。 オプションを調整するとデータを登録できます。

データベースに付属するツールで CSV を登録することもできますが、 複数のデータベースを切り替えて利用したい場合、 O/R マッパーを使って SQL を隠蔽しておくと便利なこともあります。 "csvkit" は SQLAlchemy を利用できますので、データベース接続文字列を切り替えることで ツールの接続先を変更できます。

そこで、実際に SQLite と MySQL に郵便番号データを登録してみます。

データを用意する

日本の郵便番号データを使ってみます。

ヘッダー行を定義する必要がありますので、 ファイルの先頭に次の一行を付与します。

$ sed 's/,/,\n/g' kogaki-ken-all-header.csv
jis_code,
old_code,
zipcode,
prefecture_kana,
city_kana,
town_kana,
prefecture,
city,
town,
multi_zipcode,
koaza_split,
choume_view,
multi_chouiki,
update_view,
update_reason

ヘッダー行を付けたデータを kogaki.csv とします。

$ wc -l kogaki.csv
123307 kogaki.csv

データを登録する

SQLite にデータを入れます。

$ csvsql -e shift_jis \
    --db=sqlite:///jppost.sqlite \
    --table=kogaki --insert -v kogaki.csv

MySQL にデータを入れます。

$ csvsql -e shift_jis \
    --db "mysql://root:root@localhost/jppost?charset=utf8&use_unicode=0" \
    --table=kogaki --insert kogaki.csv

それぞれのデータ件数を確認してみると、どちらも 123,306 件で一緒になっています。

$ echo "select count(*) from kogaki;" | sqlite3 jppost.sqlite
123306
$ echo "select count(*) from kogaki;" | mysql -u root -proot jppost
123306

注意点

MySQL のドライバを利用するためには、別途インストールが必要です。 また、ドライバとなるライブラリによってエンコーディングの扱いが異なるらしく、 MySQLdb のちょっと古いバージョンにはユニコード起因のバグがあるそうです。

Known Issues

MySQL-python version 1.2.2 has a serious memory leak related to unicode conversion,
a feature which is disabled via use_unicode=0. It is strongly advised to use the latest version of MySQL-Python.

他のドライバでも、接続文字列でエンコーディングに関するパラメータは必要になりますので、 SQLAlchemy のドキュメントに目を通しておくと良さそうです。

終わりに

"csvkit" に付属する csvsql を使って CSV のデータを SQLite と MySQL に登録しました。 これで郵便番号データを扱いやすくなりました。

RDB にデータを入れておくと、必要なカラムだけ抽出したり、 条件を指定してデータを取得できますので便利なことが多くなります。 SQLite を使えば単一ファイルというポータビリティは保てますので便利だと思います。

コメントを投稿