使用PyInstaller编译时mysql.connector在“except”中出现bug?
我有一个用Python写的程序,它会调用MySQL数据库,然后我用pyinstaller把它打包成一个exe文件。
在用pyinstaller打包的时候,无论是选择--onefile还是--onedir,都会出现以下问题。
我可以使用mysqldb或者mysql.connector成功连接到数据库并进行查询。
这是使用mysqldb连接的代码:
# from http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python
try:
db = MySQLdb.connect(host=hostname,user=username,passwd=password)
except MySQLdb.Error as e:
reply = QtGui.QMessageBox.critical(self, "Error",str(e.args[1]))
return
这是使用mysql.connector连接的代码:
# http://dev.mysql.com/
try:
db = mysql.connector.connect(host=hostname,user=username,password=password)
except mysql.connector.Error as e:
reply = QtGui.QMessageBox.critical(self, "Error",str(e.msg))
return
如果我提供一个错误的主机地址,那么在连接时就会抛出一个“异常”,并且错误信息会被捕获并显示出来。在我用pyinstaller打包之前,这两个连接器的异常处理都能正常工作。
但是,在我打包后的程序中,mysql.connector的“异常”处理没有发生。而mysqldb的连接调用中的异常处理正常工作,错误信息也能显示出来。
这让我得出结论,mysql.connector可能有个bug。有没有人能确认一下,还是说我哪里做错了?
2 个回答
0
我把这个答案放在这里是为了让更多人看到,因为我的解决方案的一部分被藏在了评论里。
我也遇到了同样的问题,错误的追踪信息大概是这样的:
Traceback (most recent call last):
File "main.pyw", line 239, in start
File "database.py", line 89, in connected
File "database.py", line 57, in __enter__
File "site-packages\mysql\connector\__init__.py", line 173, in connect
File "site-packages\mysql\connector\connection.py", line 102, in __init__
File "site-packages\mysql\connector\abstracts.py", line 731, in connect
File "site-packages\mysql\connector\connection.py", line 244, in _open_connection
File "site-packages\mysql\connector\network.py", line 518, in open_connection
File "site-packages\mysql\connector\errors.py", line 187, in __init__
File "site-packages\mysql\connector\locales\__init__.py", line 60, in get_client_error
AttributeError: 'module' object has no attribute 'client_error'
正如评论所说,导入的内容是:
import mysql.connector.locales.eng.client_error
9
这些工具(pyinstaller、py2app、py2exe)并不是你想的那样支持 try/except
。
生成的代码应该包含 try
和 except
这两个部分,但在判断程序实际需要哪些模块时,只会评估其中一个分支。
这可能会导致动态加载时出现各种问题。
一个简单的解决办法是直接包含所有相关的导入,比如:
import mysql
import mysql.connector
import mysql.secret_lazy_loaded_submodule
import QtGui
import QtGui.QMessageBox
import QtGui.secret_lazy_loaded_submodule
try:
mysql.connector.foo()
except Exception:
QtGui.QMessageBox.foo()