我知道有很多人遇到同样的问题,但是这是我的情况,我无法找到完全相同的问题。我正在使用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()
答案 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
那就可以了!