Python+DBMSメモ

PythonからMySQLdbやpg(PostgreSQL)やsqliteを使う場合、それぞれモジュールがあってそれを通して使うことになっているが、これらはだいたいPython Database API Specification(python.org)に準拠している(日本語訳はこちら(python.jp))ことになっている。

そしてこのAPI仕様では、DBのcursorへのexecuteメソッドでSQLを投げることになっている。私はこのexecuteメソッドに入れる文字列を作る際にescapeしなければ、いわゆる「SQLインジェクションなんとか」が起きるものと理解していた。MySQLdbにはescape_stringが定義されているのはそのためだと。

しかし、違うのですよ。sqliteモジュールにescape_stringメソッドがないので困るなぁと思ってみたけど、実際はexecuteメソッドの第1引き数がフォーマットになっていて、こいつの%s変換で勝手にescapeしてくれるのです(厳密にはparamstyleを設定するとこれ以外の書き方もできる)。例えば、

import sqlite
db=sqlite.connect("somedb", encoding="UTF-8")
c=db.cursor()
c.execute("SELECT * FROM yourtbl WHERE name=%s", ("ほげtest'in,teststr表"))

みたいな。というわけで、MySQLdbでいちいちescape_stringを通してから”format”%(args)の(Pythonの標準のフォーマット文字列変換)を使っていた私の作業は非常に無駄だったということになります。参考までに、これまではこんなカッコ悪い書き方をしていた。

import MySQLdb
db=MySQLdb.connect(db="somedb", user='name', passwd='pass')
c=db.cursor()
c.execute("SELECT * FROM yourtbl WHERE name='%s'" %(MySQLdb.escape_string("ほげtest'in,teststr表")))

ちなみにこのsqlite(sqlite.org)は非常に便利ですね。Berkley DB(sleepycat.com)系のもの並みのzero-configurationでけっこうちゃんとSQLが使えて。DBが1ファイルなので持ち運びも楽だし、コマンドも1つ。dump(mysqldumpみたいなの)はこんな感じで、そのまま食わせればいい。

 # sqlite somedb .dump > dumpfile
 # sqlite somedb2 < dumpfile

うーむ。これからはMySQL使うよりもsqlite使ってたほうがカッコいいかもな。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です