まず、SqliteやMongodbとかでやったときとの違いとしては選択出来るDriverが多いのです。
①ocpgdb1.0.3
②psycopg2-2.3.2
③PyGreSQL4.0
④pg8000-1.08
ドライバの版数は直近のものです。どれがいい・・というのは特には無さそうです。しかし、Installしてみると、④以外は全てErrorとなりました。コンパイルでエラーになるというのが共通です。何だかなー。因みに環境はFedora13+Python2.6.4+Postgresql9.0です。
サンプルみたいなものはあんまりWeb上には無いので、Manualを読みながらやってみました。
#!/usr/bin/env python
import csv
from pg8000 import DBAPI
import time
if __name__ == '__main__':
start = time.time()
c = DBAPI.connect(host="localhost",user="postgres",database="testdb")
i = 0
reader = csv.reader(open("./neta.csv"))
for row in reader:
id = row[0]
value = row[1]
cur = c.cursor()
t = (id,value,)
cur.execute("insert into hash2 values(%s,%s)",t)
i += 1
if i % 10000 == 0:
c.commit()
print "commit! %d" % i
c.commit()
c.close()
end = time.time()
print end-start
import csv
from pg8000 import DBAPI
import time
if __name__ == '__main__':
start = time.time()
c = DBAPI.connect(host="localhost",user="postgres",database="testdb")
i = 0
reader = csv.reader(open("./neta.csv"))
for row in reader:
id = row[0]
value = row[1]
cur = c.cursor()
t = (id,value,)
cur.execute("insert into hash2 values(%s,%s)",t)
i += 1
if i % 10000 == 0:
c.commit()
print "commit! %d" % i
c.commit()
c.close()
end = time.time()
print end-start
本当にあってるのか自信が持てないのですが、一応上記で動作しました。
例はCSVからデータを1行ずつ読み込んで100万件Insertするというものです。
しかし、integerの行に対してInsertするとエラーとなった為、テーブルを以下のようにしてid列をTEXT型で作成しました。
create table hash2 ( id TEXT PRIMARY KEY , value TEXT );
100万行のInsertには1145sかかりました。これはSqliteやMongodbと比較するとかなり遅いです。しかし冷静になって考えると1秒で約1000件弱Insertしているので、日頃の仕事で使っているDBと比較しても大差無いのかな、というところです。
以下、補足します。
・性能があがりそうなパラメータを少し変化させたが有意な差は得られませんでした。
(wal_buffersの値を増やす、synchronous_commitをoffにする・・・等)
・id列のPRIMERY KEYを削除してやってみましたが、やはり性能差はありませんでした。
・Python3.xにはpy-postgresqlというものがあり、ドライバの品質(ドキュメント?)的には一番良さそうな気がしました。しかし、テストアプリを作るところで挫折しました。
(Transactionの実装方式がイマイチ??です)
・DBAPI2.0ではInsertするときもCursorを使うみたいです。内部的にはPreparedStatementみたいな事もしてくれてる?かは不明です。
OSSなので当然なんですが、Pythonのドライバは有志の人が勝手に作っていて、PostgreSQLのコアメンバの人は関わっていないみたいです。コアの人たちが関わってくればもうちょい扱いやすくなるのになーと思いました。