[python] cx_Oracle 在 virtualenv 中的 pip 安装

cx_Oracle 是 Python 连接 oralce 数据库的库。而这个库并不是个完全独立自主的库,正确安装它还依赖与 oralce 的 instant client。而 InstantClient 又是区分于各个平台的。这样一来,相较于 virtualenv + pip 实现工程的的库管理以及迁移就麻烦许多。

我先实现的是 ubuntu 环境下的配置

# setup virtualenv and activiate$ virtualenv venv$ source venv/bin/activate # download oracle client, from http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html# instantclient-basic-linux.x64-11.2.0.4.0.zip# instantclient-sdk-linux.x64-11.2.0.4.0.zip# unzip oracle client to tools $ mkdir tools$ unzip instantclient-basic-linux.x64-11.2.0.4.0.zip -d tools$ unzip instantclient-sdk-linux.x64-11.2.0.4.0.zip -d tools # install cx_oracle# 注意:ORACLE_HOME 要指向绝对路径$ export ORACLE_HOME=<absolute path to tools/instantclient_11_2>$ ln -s tools/instantclient_11_2/libclntsh.so.11.1 tools/instantclient_11_2/libclntsh.so$ ln -s tools/instantclient_11_2/libocci.so.11.1 tools/instantclient_11_2/libocci.so $ pip install cx_Oracle

完成之后,venv中的python就能正确的 import cx_Oracle。因为下载的的 InstantClient 只是 zip 文件,而且只是解压到本地,所以没有相关文件安装到系统(下的rpm包还要转成deb)。

如果使用 pyinstaller 对工程再进行打包。记得在 spec 文件中加入 libociei.so 文件的包含即可。

coll = COLLECT(    importer_exe,    importer_a.binaries,    importer_a.zipfiles,    importer_a.datas,    [        ("libociei.so", "tools/instantclient_11_2/libociei.so", "BINARY")、    ],    ...

蛋疼的情况来了,我的部署环境又是 xp。所以,我还是要在 xp 上重新建起来真个 python 的开发环境。

插点题外话,对于我来说,windows 现在越来越难用了,主要是缺少梯子。而且对于越来越多来历不明的安装文件,安装起来都觉得发毛。另外,其实我对 mingw32 这类的工具包其实也没有什么好感,嵌入了很多 linux 的命令,而用法又各有各的不同。所以在 windows 下,我就基本只用 gitbash + sublimetext就够了。

安装的大致步骤其实是一样的,无非是 venv/bin 换成了 venv/Scripts,InstantClient 的 basic 和 sdk 包还是要下,只不过是换成了 nt 版本。

还有个更大的问题,因为 pip cx_oracle 还是用重新编译的,而 windows 上默认是没有编译器的(话说,有几台linux里面没有gcc呢……),所以会出现“error: Unable to find vcvarsall.bat”错误。其实运行 xp 上的 python 命令,就可以发现 “Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)] on win32″ 这行简介。其中的 MSC v.1500 就说明当前的 python 是使用 visual c++ 2008 编译的。虽然有一些解决方案是将编译器设置为 mingw32,但是我总是感觉这样似乎还是不够xp。所以,还是下了一个 visual studio 2008 express。只安装其中的 visual c++ 2008就好了。(即便这样,也占用了大概1G的空间,WTF)。安装完成以后,系统会增加一个名为“VS90COMNTOOLS”的环境变量,并指向刚才vc2008的编译器路径。就是通过这个配置,pip在编译的时候就可以找到vc的编译器了,同理。如果已经安装了其它版本的vs,可能没有这个环境变量,可能有“VS100COMNTOOLS”、“VS110COMNTOOLS”这样的环境变量。那么新建一个90的,指向它们就好了。友情提示,在这个过程中,可能需要重新开启终端,好让环境变量生效。

不过即便这样,调用 cx_Oracle 的时候还是可能出错。

>>> import cx_OracleTraceback (most recent call last):  File "<stdin>", line 1, in <module>ImportError: DLL load failed: 找不到指定的模块。

此时,就还需要拷贝 $ORACLE_HOME 文件夹内的 oci.dll, oraociei11.dll 到 venv\Lib\site-packages 内。否则,虽然可以正确import,但是在实际调用中会出现以下错误:

cx_Oracle.InterfaceError: Unable to acquire Oracle environment handle

在 spec 脚本中,与之前添加的那行换成

("oraociei11.dll", "tools\\instantclient_11_2\\oraociei11.dll", "BINARY"),

即可,不过这个dll就有100+M大小,我们自己的程序才多少东西……

至此,cx_Oracle算是能装能用了。会这么麻烦,无非还是因为oracle的闭源架构。cx_Oracle其实也只是给这个 dll 作 python 接口而已。而 oracle 的 server 安装起来就更蛋疼了。centos都要搞半天,而在ubuntu上几乎是装不起来。所以,如果是自己的项目,不管是 mySQL,postgreSQL,都比 Oracle 好用的多,而性能的话,无非就是呵呵了,千万不要被“行业的主流架构”所坑。

https://gist.github.com/noodles-v6/3737985vc编译器版本的对应关系可查看这里python中cx_Oracle模块安装遇到的问题与解决方法

[python] cx_Oracle 在 virtualenv 中的 pip 安装

相关文章:

你感兴趣的文章:

标签云: