cx_Oracleをインストールした

PythonからOracleへ接続するためにはcx_Oracleという拡張を用意する必要がある。Windows PCにインストールしたことは何度かあったが、Ubuntuには入れていなかったのでインストールしてみた。Windows向けにはインストーラが用意されているので特に悩む場面はない。しかし、Ubuntuにインストールする手順を調べるとソースコードから追加する方法を紹介しているサイトが多く、及び腰になってしまう……。cx_Oracleに限らずだけど、何かをインストールするときの手順が何種類もあって、それがapt-getからなのか、tar.gzで固められたソースを使うか、debファイルか……、錯綜していることがよくある。RHEL系の情報を参考にできたりできなかったりすることもあり、悩むことが多い。そのなかでもソースコードから……ってのは最後の手段にしたい。
easy_installを使いました。

環境

  • Xubuntu 11.10 (32bit)
  • Oracle 10g Express Edition (XE) Clientをインストール済み

Oracleがインストールされていないとエラーでた

$ sudo easy_install cx_Oracle
sudo: unable to resolve host kosuke-Lenovo-G565
[sudo] password for kosuke: 
Searching for cx-Oracle
Reading http://pypi.python.org/simple/cx_Oracle/
Reading http://cx-oracle.sourceforge.net
Reading http://starship.python.net/crew/atuining
Best match: cx-Oracle 5.1.1
Downloading http://prdownloads.sourceforge.net/cx-oracle/cx_Oracle-5.1.1.tar.gz?download
Processing cx_Oracle-5.1.1.tar.gz
Running cx_Oracle-5.1.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-g8jJW7/cx_Oracle-5.1.1/egg-dist-tmp-zEOkYH
error: cannot locate an Oracle software installation
$

「error: cannot locate an Oracle software installation」はOracleが入ってないから続行できないといった意味だろうな。rootユーザに環境変数ORACLE_HOME」が設定されていないからだ、ということはすぐわかった。

少し調べてわかったが、「sudo」に「-E」をつけると環境変数を引き継いでくれるらしい。

Python.hがないのでコンパイルを続行できない

$ sudo -E easy_install cx_Oracle
sudo: unable to resolve host kosuke-Lenovo-G565
Searching for cx-Oracle
Reading http://pypi.python.org/simple/cx_Oracle/
Reading http://cx-oracle.sourceforge.net
Reading http://starship.python.net/crew/atuining
Best match: cx-Oracle 5.1.1
Downloading http://prdownloads.sourceforge.net/cx-oracle/cx_Oracle-5.1.1.tar.gz?download
Processing cx_Oracle-5.1.1.tar.gz
Running cx_Oracle-5.1.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-nuDNw4/cx_Oracle-5.1.1/egg-dist-tmp-Lxrpld
cx_Oracle.c:6:20: 致命的エラー: Python.h: そのようなファイルやディレクトリはありません
コンパイルを停止しました。
error: Setup script exited with error: command 'gcc' failed with exit status 1

Python.hがないとsetup.pyを続行できないらしい。
今のXubuntuに入っているPythonでeasy_installはおろか、setup.pyを実行して拡張モジュールをインストールしたことが全くなかったのでちょっと悩んだけど、「python-dev」というパッケージを追加すればいいらしい。

$ sudo apt-get install python-dev
sudo: unable to resolve host kosuke-Lenovo-G565
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  libexpat1-dev libssl-dev libssl-doc python2.7-dev zlib1g-dev
以下のパッケージが新たにインストールされます:
  libexpat1-dev libssl-dev libssl-doc python-dev python2.7-dev zlib1g-dev
アップグレード: 0 個、新規インストール: 6 個、削除: 0 個、保留: 0 個。
7,697 kB のアーカイブを取得する必要があります。
この操作後に追加で 21.0 MB のディスク容量が消費されます。
続行しますか [Y/n]? 
(※以下省略)

たぶんこの問題は他のモジュールをインストールするときにも出る気がする。

インストール成功と確認

このあとでもう一度easy_installからのインストールを試みたところ、エラーなく正常終了。

$ sudo -E easy_install cx_Oracle
sudo: unable to resolve host kosuke-Lenovo-G565
Searching for cx-Oracle
Reading http://pypi.python.org/simple/cx_Oracle/
Reading http://cx-oracle.sourceforge.net
Reading http://starship.python.net/crew/atuining
Best match: cx-Oracle 5.1.1
Downloading http://prdownloads.sourceforge.net/cx-oracle/cx_Oracle-5.1.1.tar.gz?download
Processing cx_Oracle-5.1.1.tar.gz
Running cx_Oracle-5.1.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-vdvi8V/cx_Oracle-5.1.1/egg-dist-tmp-3MO9nA
In file included from /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/oci.h:2655:0,
                 from cx_Oracle.c:10:
/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/oci1.h:148:1: 警告: 関数宣言がプロトタイプではありません [-Wstrict-prototypes]
(※同じような警告が続く)
[-Wunused-but-set-variable]
zip_safe flag not set; analyzing archive contents...
Adding cx-Oracle 5.1.1 to easy-install.pth file

Installed /usr/local/lib/python2.7/dist-packages/cx_Oracle-5.1.1-py2.7-linux-i686.egg
Processing dependencies for cx-Oracle
Finished processing dependencies for cx-Oracle

インストールできたので、インタラクティブシェルから動作確認してみる。

$ python
Python 2.7.2+ (default, Oct  4 2011, 20:03:08) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>> cx_Oracle.clientversion
<built-in function clientversion>
>>> cx_Oracle.clientversion()
(10, 2, 0, 1, 0)
>>> 

大丈夫そうだ。使い方は標準で入っているsqlite3用モジュールやDB接続用モジュールとほとんど同じ。どれかひとつでも使ったことがあれば直感的にわかるレベルだと思う。