在 Windows 上用 PyInstaller 打包 cx_Oracle

最近準備要把手邊用 python 做的小工具交給別人使用,如果可以直接給 code 是最簡單的,但有執行上的難度,所以用 PyInstaller 包成一個執行檔,避免一些安裝、環境、dependency 等等的問題,但 script 裡有用到 cx_Oracle,所以打包的方式有點不同,筆記一下。

目前 PyInstaller 3.5 用在 python 3.8 上好像有點問題,所以本機上的 python 裝的是 3.7.5。事前安裝 Oracle Instant Client 和 cx_Oracle 的部份可以參考 cx_Oracle 的安裝說明,不過我裝了文件裡提的 Visual Studio redistributable 還是沒辦法裝 cx_Oracle,最後是另外安裝 Build Tools for Visual Studio 2019 才行,詳見前篇

一般要打包成單一一個可執行檔是用 -F 參數:

pyinstaller -F the_script.py

此時除了包好的 exe 檔在 dist/ 下外,還會有另一個 .spec 檔。修改 spec 文件,把 Oracle Instant Client 的 dll 檔加進去。

exe 區段裡的 a.binaries 要改成 a.binaries+[('oraociei19.dll','oraociei19.dll','BINARY')], 其中 oraociei19.dll 依據使用的 Oracle Instant Client 版本而定,以我的例子裝的是 v19。

改好的 spec 檔大概會長這樣:

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    
    a = Analysis(['check-pcu-cr-status.py'],
                 pathex=['C:\\Users\\Administrator\\Documents\\linebot'],
                 binaries=[],
                 datas=[],
                 hiddenimports=[],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              a.binaries+[('oraociei19.dll','oraociei19.dll','BINARY')],
              a.zipfiles,
              a.datas,
              [],
              name='check-pcu-cr-status',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              upx_exclude=[],
              runtime_tmpdir=None,
              console=False )

oraociei19.dll 檔 copy 到 script 所在目錄,接著執行 pyinstaller -F the_script.spec 即可。

參考:Pyinstaller: cx_Oracle.InterfaceError: Unable to acquire Oracle environment handle


Leave a Reply