将cx_Oracle部署到各种版本的Oracle Client


问题内容

我有一些使用cx_Oracle连接到Oracle数据库的小型python应用程序。我通过使用py2exe编译这些应用程序来部署它们,在许多情况下都可以正常工作。

问题是,在需要安装此软件的许多人中没有标准的Oracle Client版本(例如9i和10g),试图让所有人都对一个Oracle
Client版本进行标准化将非常令人沮丧。目前,我将9.2客户端与cx_Oracle
4.4.1一起用于9i,因此当我py2exe时,生成的exe包含cx_Oracle 4.4.1库,并且不能与10g客户端一起使用。

我没有使用任何Oracle版本的任何特定功能,因此,除了cx_Oracle兼容性问题之外,我没有任何理由关心正在使用的客户端版本。

理想的解决方案是以某种方式编译完全独立于计算机上安装的Oracle Client的版本。

如果那不可能,我将愿意为每个主要的Oracle版本(my_app_9i.exe,my_app_10g.exe等)编译单独的exe,但是我什至找不到简单的方法来执行此操作,因为安装新的cx_Oracle会覆盖我的在旧版本中,每当我进行更改时,我都必须不断地来回交换库以编译其他版本。

欢迎任何建议或其他选择。


问题答案:

如果要构建多个cx_Oracle版本(例如:cx_Oracle10g,cx_Oracle11g等),则需要修改cx_Oracle
setup.py脚本。脚本的最后一步是对setup();的调用。第一个参数是要构建的模块的名称。您所需要做的就是将更"cx_Oracle"改为"cx_Oracle" + ver,其中ver是10g11g等等。创建多个脚本并对其进行硬编码,或者添加另一个参数以setup.py动态选择它。

当然,一旦掌握了这一点,就需要一种在运行时加载正确模块的机制。为此,您需要创建自己的cx_Oracle模块,该模块的__init__.py文件如下所示:

try:
  from cx_Oracle9g import *
except ImportError:
  try:
    from cx_Oracle10g import *
  except ImportError:
    try:
      from cx_Oracle11g import *

您需要做的就是随您的应用程序一起交付自定义cx_Oracle模块以及正确的cx_OracleXg模块。

或者,您可以让自定义cx_Oracle模块动态检查每个可用的Oracle客户端库(9g,10g,11g等),然后仅导入正确的匹配cx_OracleXg模块。在这种情况下,您只需要运送一个二进制文件,其中包含您的自定义cx_Oracle模块以及所有cx_OracleXg模块。