| ■ | zxJDBCによるデータベース操作 |
●zxJDBC
Pythonの世界には、
Python Database APIという、
Python言語からRDBMS(リレーショナルデータベース管理システム)
を操作するための拡張モジュールを開発する際のAPI規約があり、
普通のPython(CPython)からOracle、Sybase、MySQL、PostgreSQL
などのRDBMSに接続してデータを操作するためのモジュールがたくさん開発されています。
DBモジュールの分室でご紹介している
cx_Oracle、PygreSQL、MySQLDBなどは、それらの有名な一部です
(どれがどのRDBMSに接続するモジュールかは名前を見れば一目瞭然ですよね?)。
同じことはJavaでも可能です。但しJavaの場合は既にJDBCという今度はJava言語のAPI
がありますから、
JDBCをさらにPython DB APIでラップしたモジュールがあればよいわけです。
その標準の地位にあるのがzxJDBCと呼ばれるモジュールで、
これはJythonのバージョン2.1から本体に同梱されています。
zxJDBCを使うと、Jythonからデータベース操作をするときに、
前のページのようにいちいちJDBCのクラスを使う必要はなく、
たいへん便利に使うことができます。
zxJDBCでデータベース操作ができる環境は、
JDBCでデータベース操作ができる+Jython+zxJDBCです。
先述したように、Jython 2.1以降にはzxJDBCが入っています。
そうでない場合は上記のzxJDBCのホームページから入手できます。
JDBCでデータベース操作ができる環境とは、
というのはこのサイトの趣旨から大きく脱線するので省きますが、
おおざっぱーにいうとRDBMSのネイティブクライアント
(OracleならSQL*Plus、MySQLならmysqlコマンドとか)でデータベースサーバに接続できること、
J2SE 1.3とか1.4とか、及び各RDBMSに合ったJDBCドライバを入手していることです。
ここではWindows XP上でローカルホストのMySQLにJython 2.1付属のzxJDBCで接続を試しました。
●とりあえず接続して、検索する
#
# zxjdbctest1.py
# Jythonでzxjdbcのテスト(表の全件SELECT)
# 2003/01/08
#
from com.ziclix.python.sql import zxJDBC
con = zxJDBC.connect("jdbc:mysql://localhost/udb", None, None, "org.gjt.mm.mysql.Driver")
# optionally
#>>> db = zxJDBC.connect(d, u, p, v, CHARSET='iso_1')
cur = con.cursor()
sql = """
SELECT SHITEN_CODE, SHITEN_NAME
FROM SHITEN
"""
cur.execute(sql)
rset = cur.fetchall()
print "%d行のデータが 見つかりました。" % cur.rowcount
for e in rset:
print "%-5s %-30s" % e
print "ok."
cur.close()
con.close()
# end.
|
●データソースを使ったり、バインド変数を使ったりする
#
# zxjdbctest2.py
# Jythonでzxjdbcのテスト
# ・接続に引数の代わりにデータソース(DataSource)を使用
# ・検索条件にバインド変数を使用。zxJDBCのプレースホルダはqmark(?)です。
# 2003/01/08
#
import sys
from com.ziclix.python.sql import zxJDBC
print zxJDBC.paramstyle
params = {}
params['serverName'] = "localhost"
params['databaseName'] = "udb"
params['user'] = "urano"
params['password'] = ""
params['port'] = 3306
try:
con = apply(zxJDBC.connectx, ("org.gjt.mm.mysql.MysqlDataSource",), params)
except zxJDBC.DatabaseError, e:
print "データベースに接続できませんでした。"
print "原因:" + e[0]
sys.exit(1)
cur = con.cursor()
sql = """
SELECT SHITEN_CODE, SHITEN_NAME
FROM SHITEN
WHERE SHITEN_NAME = ?
"""
cur.execute(sql, ("福岡",))
rset = cur.fetchall()
if cur.rowcount > 0:
print "%d行のデータが 見つかりました。" % cur.rowcount
for e in rset:
print "%-5s %-30s" % e
print "ok."
else:
print "該当データが見つかりませんでした。"
print "sad."
cur.close()
con.close()
# end.
|
今度は接続時のエラー処理もしてみましょう。 接続エラーが起きたときはサンプルのようにzxJDBC.DatabaseError (Javaのjava.io.SQLExceptionみたいなもの)が発生するので、 適切に処理を書いてやればよいだけです。
はてさて、WHERE句で条件を指定したSQL文を発行するときなどに大変重宝するのがバインド変数です。 Python DB APIではモジュールごとにバインド変数の位置をSQL文中で指定するためのプレースホルダの記法を選ぶことができますが、 「print zxJDBC.paramstyle」すると「qmark」と表示されるとおり、 zxJDBCのプレースホルダはハテナマーク(?)です。 これはJDBCの記法と同じ(java.io.PreparedStatementで使うプレースホルダと同じ) なので、分かりやすいと思います。
セクションのサブメニューに戻る
(first uploaded 2003/01/08 last updated (not ever))