Search code examples
pythondb2pyinstaller

ibm_db, pyinstaller, DLL issue


My Question Is:
I am trying to package a simple code which is mentioned below that has import ibm_db, but I am not able to do it, as it is giving me the below-mentioned error. I have researched a lot on SO and other websites, but most of the solutions that I have encountered say to add the DLL's using --add-binary, I have tried that as well, but still, I am getting the below-mentioned error.
I am using a Windows 10 64-Bit OS, x64-based processor.
I am using a virtual environment created using python -m venv env
The packages mentioned below are installed in my virtual environment.
I hope all these details are enough and qualify as a question.

-- PYTHON VERSION --
Python 3.7.8

-- PYTHON PACKAGES INSTALLED --
altgraph 0.17
future 0.18.2
ibm-db 3.0.2
pefile 2019.4.18
pip 20.1.1
PyInstaller 3.6
pywin32-ctypes 0.2.0
setuptools 47.1.0

-- MY CODE --

import ibm_db<br>
print(ibm_db.`__version__`)<br>

-- USING PYINSTALLER TO CREATE PACKAGE FOR MY ABOVE CODE --
pyinstaller --noconfirm ^
--name=test ^
--hidden-import "pkg_resources.py2_warn" ^
--add-binary C:\Users\vrajendrasinghpar\Desktop\test\env\Lib\site-packages\ibm_db_dlls\ibm_db.dll;.\ibm_db_dlls ^
test_ibm_db.py

-- GETTING THE BELOW ERROR --

Traceback (most recent call last):<br>
  File "test\test_ibm_db.py", line 1, in `<module>`<br>
  File "c:\users\vrajendrasinghpar\desktop\test\env\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module<br>
    exec(bytecode, module.`__dict__`)<br>
  File "lib\site-packages\ibm_db.py", line 28, in `<module>`<br>
  File "lib\site-packages\ibm_db.py", line 26, in `__bootstrap__`<br>
  File "imp.py", line 345, in load_dynamic<br>
ImportError: DLL load failed: The specified module could not be found.<br>
[27420] Failed to execute script test_ibm_db<br>

Solution

  • Your question does not mention whether the build hostname is the same as the run hostname.

    This answer assumes you are running the built executable (output of pyinstaller) on an Microsoft-Windows hostname different from the build hostname.

    If you are using the IBM supplied clidriver (which is the default for python ibm_db) , and if this is not already installed on the target environment, and if an alternative IBM supplied Db2 CLI driver is also not preinstalled on the target environment then you must bundle clidriver with your pyinstaller output at build time.

    You can include the clidriver tree contents with the following additional argument to pyinstaller:

    --add-data="c:\path\to\clidriver;.\clidriver" ^

    You can find the path to the clidriver with pip show ibm_db and append clidriver to the Location: name.

    If you do bundle like this, there are some considerations:

    • your bundle is "frozen in time". When IBM updates its clidriver then your previously built executables won't benefit from the security fixes ,defect fixes and enhancements until and unless you re-run pystaller to include the latest clidriver, and redistribute. IBM typically updates this clidriver at least twice per year. This is particularly important if you are using encrypted connections (TLS/SSL).

    • your bundle size will increase in size due to the inclusion of clidriver within it.

    • on the target Microsoft-Windows environment, after you unzip your dist\$name , you may need to run the clidriver\bin\db2cli install -setup to register the component with Microsoft Windows. This allows the odbcad32 to be aware of the driver and allow some configuration functionality via the odbcad32 GUI.

    • Any dependencies of clidriver must also be met on each target hostname.