cx_Oracle で python から Oracle に接続する

SQL*Plus があまりにも使いにくいので、cx_Oracle を使って python から、別のサーバにある Oracle DB へ接続する環境を整えたのでその時のメモ。最初は Cygwin 環境に作ろうとしたが何故かうまくいかず、結局 VMWare を入れて環境を作ることにした。
使用環境は VMWare Player + Ubuntu 10.04 Desktop と Python 3.1, Oracle XE 10g

def __mopemope__(self, *args, **kwargs)プログラマの実態を大いに参考にさせて頂いた。感謝。

まず OracleXE をインストールする。インストールがうまくいけば、アプリケーションのメニューに Oracle Database 10g Express Edition のメニューが追加されているはずだ。「SQL コマンドラインの実行」をクリックすると SQL*Plus が起動するので、DB サーバに接続出来るか確認しておく。

つぎに cx_Oralce のインストール。linux 向けの cx_Oracle のバイナリは .rpm でしか提供されていないようで、alien コマンドを使い .deb ファイルへの変換を試みたのだが、

hal@ubuntu-vm:~/dist$ sudo alien cx_Oracle-5.1-10g-py26-1.i386.rpm 
[sudo] password for hal: 
error: incorrect format: unknown tag

というエラーが出てしまったので、ソースからビルドすることにした。

cx_Oracleから、現時点で最新版の 5.1 のソースをダウンロードする

解凍したあとは、環境変数を設定して、ビルドするだけ。

$ export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib
$ tar xvfz cx_Oracle-5.1.tar.gz 
$ cd cx_Oracle-5.1
$ python setup.py build
$ sudo env ORACLE_HOME=$ORACLE_HOME python setup.py install

setup.py が、Oracle のバージョンまでチェックしてくれる。
インストールがうまくいけば、site-packages の下に cx_Oracle.so が出来てるはず:

hal@ubuntu-vm:/usr/lib/python3.1/site-packages$ ls -ltr
合計 276
-rwxr-xr-x 1 root root 273240 2011-03-20 08:29 cx_Oracle.so
-rw-r--r-- 1 root root    896 2011-03-20 08:29 cx_Oracle-5.1-py3.1.egg-info

尚、ビルドにあたり、 G.Akahane さんの「プログラマの実態」にあったパッチは必要無かった。(cx_Oracle のバージョンが違うためだと思われる)

cx_Oracle を使ったサンプル:

import sys
import cx_Oracle

def show(cur):
	while 1:
		line = cur.fetchone()
		if line is None:
			break
		print( line )

#
connection = cx_Oracle.connect("user/pass@hostname:port/sid")
cur = connection.cursor()

needCommit = False

for query in sys.stdin:
	print( query )
	cur.execute(query)
	if query.upper().startswith("SELECT"):
		show(cur)
	else:
		needCommit = True

if needCommit:
    connection.commit()

cur.close()
connection.close()

標準入力からクエリを受け付けるので、シェルプロと組み合わせることで、かなり仕事が楽になる。はずだ。


これでとりあえず動く環境は出来たが、DB に入っている日本語のデータが文字化けしてうまく出ない。
この問題は時間があれば調べてみる予定。