データベースを使っていると、よくcsvファイルと相互に変換したくなります。MySQLやPostgreSQLでは標準でcsvのインポート/エクスポートができるので、SQLiteでも出来るだろうという事で調べてみました。
結論から言うとSQLiteで使えるCSVのインポート/エクスポートは制約が強くて使い辛いです。というのも、カラムの文字列内にセパレータ(標準ではカンマ)が含まれている場合は、クォートされていても、セパレータとして認識されてしまい、正常なcsvとして扱われないからです。(例えば”Hi, Nice to meet you.”は2カラムとして扱われます。)
ちなみにSQLite標準のインポート/エクスポートは以下のように行います。
# 標準で以下のようにインポート/エクスポートできるが、セパレータが上手くパースされない .mode csv TABLE_NAME # エクスポート SELECT * FROM TABLE_NAME # インポート .import sample.csv TABLE_NAME
カラム内にセパレータが無ければ標準のままで行けますが、そんな事はイチイチ考えてられないので、pythonで簡単にインポート/エクスポートを実装してみました。
#!/usr/bin/python # -*- coding: utf-8 -*- import sqlite3 import csv # SQLite内のデータはutf-8を想定 def sqlite2csv(db_name, table_name, out_filename): dbh = sqlite3.connect(db_name) writer = csv.writer(file(out_filename, 'w')) for row in dbh.execute('SELECT * FROM %(table_name)s' % locals()): writer.writerow([col.encode('utf-8') if isinstance(col, unicode) else col for col in row]) dbh.close() # csvのセパレータはカンマを想定 def csv2sqlite(db_name, table_name, in_filename): dbh = sqlite3.connect(db_name) reader = csv.reader(open("import.csv", "rb")) for row in reader: ph = "?," * (len(row) - 1) + "?" dbh.execute("INSERT INTO %(table_name)s VALUES(%(ph)s)" % locals(), tuple(row)) dbh.commit() dbh.close()
これでSQLiteとCSVが相互に行き来できるようになりましたね。ま、最初からMySQL/PostgreSQLを使えよというのが最もかもですが。

