MySQLのPythonインターフェース:MySQLdb

 MySQLdbモジュールは、 検索の高速性に定評があるオープンソースのRDBMS、 MySQLにPythonでアクセスするためのインターフェースです。 元々はAndy Dustman氏によって開発され、フリーウェアとして公開されてきましたが、 現在はオープンソースとなり、上記リンクの通りSourceForgeに総本山が置かれています。 MySQLdbはPythonのデータベースモジュールの標準ガイドラインである、 Database API 2.0に準拠したつくりになっているので、 他のデータベースモジュールからの移行もすんなりできると思います。 現在の安定バージョンは0.9.1で、0.9.2の試行版(Test Release)も公開されています。

サンプルその1
下のサンプルはMySQLdbのサンプルであると同時に、 PythonのDB APIに準拠したモジュールに普遍的に使いまわしが利くコード例といえましょう。

# MySQLDB 0.9.1のテスト
# 2002/03/11
import MySQLdb

# MySQLデータベースに接続するには、MySQLdb.connectを使います。
# これは接続オブジェクトを返します。
# 引数は全部で7つ(db, host, port, opt, tty, user, passwd)
# で、host以下は省略可能です。
con = MySQLdb.connect(db="udb", host="localhost", port=3306,
                      user="urano", passwd="urano398")
# カーソルの作成
cur = con.cursor()
# SQL文で問い合わせを実行します。
s = "SELECT KANJI_NAME, MAIL_ADDRESS FROM USERS"
cur.execute(s)

# 結果を1行ずつ取得
r = cur.fetchone()
while r != None:
  print "%-10s | %-40s" % r
  r = cur.fetchone()

# カーソルを閉じます。
cur.close()

# closeメソッドでデータベース接続を終了します。
con.close()
# end.

 MySQLの場合は、接続の際に db、user、passwdの3つは最低でも指定する必要があります。 リモートクライアントから接続する際には、host=でMySQLサーバ機のホスト名も指定します。 cursor()でカーソルを開き、execute()で実行、fetchall()で結果を取得、 close()で接続終了、というDB APIの流れはOracleのC言語API、 OCIの概念に近いと思われます。 この中で、execute()は、複数回実行するとそのたびにSQL文を構文解析しているように見えますが、 このexecute()は一般的な実装では一度解析されたSQL文をキャッシュしていて、 繰り返し同じSQL文が実行されるときには解析の手間を省いて高速化が図られているそうです。

モジュール固有のパラメータ書式を知る
 Python Database APIでは、拡張モジュールがSQL文に含めるプレースホルダ (パラメータ記述子)の形を複数の種類から選択できるようにしています。 これは、モジュールの読み出し専用のクラス変数、 paramstyleで知ることができます。 例えば、MySQLdbでのパラメータ書式は次のようにして知ります。

import MySQLdb
print MySQLdb.paramstyle

これを実行すると、「format」と表示されます。 これがMySQLdbの場合のプレースホルダの指定方法です。 …といっても、具体的には??ですね。 その一覧を表示すると、下のようになります。

paramstyleパラメータ書式
qmarkJDBCのPreparedStatement(準備文)のように、 パラメータを "?" で表現します。
numericパラメータをコロン:と、連番の整数で":1"のように書きます。
namedOracleのバインド書式のように、コロン:と任意の名前から":username" のように書きます。
formatC言語のprintf書式に準拠した書式。例えば、文字列パラメータなら"%s"です。
pyformatPython独自の拡張フォーマット。よく知りませんが、 マニュアルによると '%(name)s' のようにパラメータ名とそのデータ型を同時に表現できるようです。

サンプルその2
 今度のサンプルは、そのパラメータのついたSQL文を使ったスクリプトです。 先の実験の通り、MySQLdbのparamstyleは「format」 ですから、パラメータは%sなどのprintf書式で指定することになります。

# MySQLDB 0.9.1のテスト(2)
# 2002/07/15
import MySQLdb

# MySQLデータベースに接続するには、MySQLdb.connectを使います。
# これは接続オブジェクトを返します。
# 引数は全部で7つ(db, host, port, opt, tty, user, passwd)
# で、host以下は省略可能です。
con = MySQLdb.connect(db="udb", host="localhost", port=3306,
                      user="urano", passwd="urano398")
# カーソルの作成
cur = con.cursor()
# SQL文で問い合わせを実行します。
s = "SELECT KANJI_NAME, MAIL_ADDRESS FROM USERS WHERE USERNAME = %s"
cur.execute(s, ["uranom"])
# 結果をたっぷるのリストで取得
rset = cur.fetchall()
# カーソルを閉じます。
cur.close()

# 結果の表示
print "rows=%d" % cur.rowcount
for e in rset: print "%-10s | %-40s" % e
print "ok."

# closeメソッドでデータベース接続を終了します。
con.close()
# end.

 カーソルの読み出し専用属性rowcountは、 直前のSQL文が作用したDB上の行の数を表します。 これは、UPDATE文、INSERT文などの作用した行の数であるほか、 SELECT文で選択された行の数も知ることができます。

セクションのサブメニューに戻る
(first uploaded 2002/03/11 last updated 2002/07/16)