ImportError:DLL加载失败:找不到指定的模块-IBM DB2

时间:2019-04-24 22:51:31

标签: python-3.x db2 pyinstaller

我知道有很多人遇到同样的问题,但是这是我的情况,我无法找到完全相同的问题。我正在使用pyinstaller构建可执行文件,并且不断收到importError。我正在使用ibm_db软件包连接到IBM DB2数据库,并使用pandas to_sql方法将其插入表中。在添加SQL代码之前,我在程序上使用pyinstaller,因此我很确定它与尝试连接到DB2有关,但是对于我来说,我一生都无法解决。

我在运行pyinstaller时收到很多警告和信息消息,但没有看到任何错误。只有在尝试执行pyinstaller生成的可执行文件时,我才会收到错误消息。

我试图在虚拟环境中运行它以试图找出问题,但是我对虚拟环境并不熟悉,所以我不再尝试使用它。

Traceback (most recent call last):
  File "rebate_gui_sql.py", line 9, in <module>
  File "c:\users\dt24358\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "site-packages\ibm_db.py", line 10, in <module>
  File "site-packages\ibm_db.py", line 9, in __bootstrap__
  File "imp.py", line 342, in load_dynamic
ImportError: DLL load failed: The specified module could not be found.
[11020] Failed to execute script rebate_gui_sql

更新:2019/5/1从下面的评论,这是我的简单程序

import pandas as pd
from tkinter import *
from tkinter import ttk
import ibm_db
import ibm_db_dbi as db
from sqlalchemy import create_engine

class Application(Frame):

    def __init__(self, master):
        ttk.Frame.__init__(self, master)  
        self.master = master
        self.run_process()

    def run_process(self):
        engine = create_engine("db2+ibm_db://userid:password@url:port/database")
        conn = engine.connect()
        print("Connected to " + str(engine))

        sql = '''
            Select *
            from rebteam.pd5
            fetch first row only
            '''

        df = pd.read_sql(sql, conn)
        print(df)

        df.to_csv(r'c:\users\dt24358\scripts\pricing tool\GUI_SQL\test.csv', index=False)
        self.result_label = Label(root, text="Select of PD5 Successful", bg="light green", width=80, justify=LEFT)
        self.result_label.grid(row=0,columnspan=2)

root=Tk()
root.title("Rebate Bid Data Upload")
root.configure(background="light green")
app = Application(root)
root.mainloop()

2 个答案:

答案 0 :(得分:1)

此答案与以下版本有关:

pyinstaller 3.4  
setuptools 41.0.1 
ibm_db 3.0.1
ibm_db_sa 0.3.4
sqlalchemy 1.3.3

这里有两个独立的问题。

直接的问题(ImportError)是无法加载ibm_db.dll

发生ImportError是因为pyinstaller不会将外部(非python)库复制到捆绑软件中,除非您明确要求这样做。

pyinstaller选项--add-binary提供了此ImportError的解决方法,请参见下面的示例。

如果您的python脚本使用SQLAlchemy访问Db2,则在使用pyinstaller构建后,您可能会在运行时看到第二个症状。运行时症状为:

  

“ sqlalchemy.exc.NoSuchModuleError:无法加载插件:   sqlalchemy.dialects:ibm_db_sa“

  

“ sqlalchemy.exc.NoSuchModuleError:无法加载插件:   sqlalchemy.dialects:db2.ibm_db“

(取决于给create_engine()的url前缀)

此症状sqlalchemy.exe.NoSuchModuleError并非特定于Db2,但当通过SQLAlchemy与 external 方言(Db2,teradata,snowflare,presto)一起使用时,可能会影响其他数据库,...)。使用SQLAlchemy内部方言的数据库可以直接使用。

这里是一种解决方法,其他解决方法也是可能的。

SQLAlchemy外部方言使用pkg_resources entry_points允许SQLAlchemy利用它们,但是pyinstaller在没有您帮助的情况下仍无法处理它们。此类入口点信息是有关模块的一种元数据。

此解决方法使用pyinstaller挂钩收集相关模块的元数据,并告诉pyinstaller包含这些挂钩文件的目录。对于带有SQLAlchemy的Db2,需要三个钩子文件hook-ibm_db.py, hook-ibm_db_sa.py, hook-sqlalchemy.py。我选择将这些挂钩文件与源文件python脚本放在同一目录中。

每个文件的内容都是很短的两行,并且内容仅因其中包含的模块名称而不同。以下是其中一个文件hook-sqlalchemy.py的示例(对于其他两个必需文件,只需适当地替换模块名称即可):

from PyInstaller.utils.hooks  import  copy_metadata

datas = copy_metadata('sqlalchemy')

要通过ibm_db.dll添加--add-binary method,可以使用命令行选项pyinstaller或编辑规范文件。

因此对于这两种解决方法,假设您的ibm_db.dll位于以下目录中:

%LOCALAPPDATA%\programs\python\python37\lib\site-packages\ibm_db_dlls

,然后创建一个变量以指向该位置:

> set ibm_db_path=%LOCALAPPDATA%\programs\python\python37\lib\site-packages\ibm_db_dlls

对于MS-Windows批处理文件(使用^作为行连续字符),用于处理上述两种变通方法的pyinstaller命令行示例为:

pyinstaller -y ^
--additional-hooks-dir=. ^
--hidden-import ibm_db_sa.ibm_db ^
--hidden-import ibm_db_dbi ^
--hidden-import ibm_db ^
--add-binary  %LOCALAPPDATA%\Programs\Python\Python37\Lib\site-packages\ibm_db_dlls\ibm_db.dll;.\ibm_db_dlls ^
 your_script.py

注释:

  • 如果您的python脚本明确导入了模块,则您不会 需要通过--hidden-import选项指定它们(购买仍然需要 钩子。)

  • ibm_db.dll必须位于您的子目录ibm_db_dlls中 捆绑软件,这就是在 --add-binary选项。

  • 如果要针对Linux / Unix构建,请使用^代替。照常使用\作为行继续符。

答案 1 :(得分:0)

感谢您的提问和回答。我在Windows7 Python3.7 ibm-db 3.0.1中遇到了相同的情况
根据您的提示,我认为原因是exe在clidriver \ bin和ibm_db.dll中找不到* .dll, 并用类似的方法分两步解决

拳头: 与您相同,将clidriver目录添加到系统路径

**\site-packages\clidriver\bin

第二 带参数--add-binary

 Pyinstaller --add-binary **\Lib\site-packages\ibm_db_dlls\ibm_db.dll;.\ibm_db_dlls myproject.py

那就可以了!

类似的问题: PyQt5 Executable is crashing with Missing DLL