如何将 cx_oracle 与 Pyinstaller 捆绑在一起

How to bundle cx_oracle with Pyinstaller

我的目标是使用 Pyinstaller 从使用 Tkinter 和 cx_oracle 访问数据库的简单 python 脚本中捆绑一个 exe 文件。 python 代码是在安装了 Anaconda、cx_oracle 软件包和 oracle 客户端的 windows 机器上开发的。然后我需要运行许多目标windows机器没有oracle客户端或Python的exe文件.

我在开发机器上使用 Python 2.7 和 Pyinstaller 3.1。

网上找了好久,只找到一个教程: https://mail.python.org/pipermail/tutor/2014-December/103608.html

我按照相同的步骤修改了 spec 文件如下:

# -*- mode: python -*-

block_cipher = None


a = Analysis(['mycode.py'],
             pathex=['C:\Users\myuser\PycharmProjects\mycode'],
             binaries=None,
             datas=None,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries + [('oraociei11.dll','D:\ProgramFiles\Anaconda2\oraociei11.dll','BINARY')],
          a.zipfiles,
          a.datas,
          name='mycode',
          debug=False,
          strip=False,
          upx=True,
          console=True )

捆绑包有效。原来安装oracle客户端的机器上的代码运行s。但是在没有 oracle 客户端的单独机器上,它无法 运行,并显示以下错误消息:

Exception in Tkinter callback Traceback (most recent call last): File "lib-tk\Tkinter.py", line 1537, in call File "", line 152, in login DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be loaded: "The specified module could not be found". See https://oracle.github.io/odpi/doc/installation.html#windows for help

现在我很困惑需要哪些步骤才能安全地将 python 脚本中的 exe 与 cx_oracle 捆绑在一起,以便它可以 运行 在 windows 上没有oracle客户端的机器?或者我 "have to" 在目标机器上安装 oracle 客户端?

我真的希望找到比我在上面找到的旧 link 更详细的关于将 cx_oracle 与 pyinstaller 捆绑在一起的教程。

cx_Oracle 需要 Oracle 客户端。您需要在目标机器上安装它!请注意错误消息中的 link:https://oracle.github.io/odpi/doc/installation.html#windows。它应该可以帮助您完成 cx_Oracle 在目标机器上工作所需的一切。

感谢您提出这个问题。你走在正确的道路上。您只缺少其他 .dll 文件。您需要将在 Oracle 即时客户端文件夹中找到的所有 .dll 文件添加到 .spec 文件中。请参阅下面我为即时客户端 19.10 所做的示例:

a.binaries = a.binaries + [('oraociei19.dll','.\instantclient_19_10\oraociei19.dll','BINARY')]
+ [('orannzsbb19.dll','.\instantclient_19_10\orannzsbb19.dll','BINARY')]
+ [('oraocci19d.dll','.\instantclient_19_10\oraocci19d.dll','BINARY')]
+ [('oraocci19.dll','.\instantclient_19_10\oraocci19.dll','BINARY')]
+ [('oci.dll','.\instantclient_19_10\oci.dll','BINARY')]
+ [('ocijdbc19.dll','.\instantclient_19_10\ocijdbc19.dll','BINARY')]
+ [('ociw32.dll','.\instantclient_19_10\ociw32.dll','BINARY')]
+ [('oramysql19.dll','.\instantclient_19_10\oramysql19.dll','BINARY')]
+ [('oraons.dll','.\instantclient_19_10\oraons.dll','BINARY')]
+ [('orasql19.dll','.\instantclient_19_10\orasql19.dll','BINARY')]