使用PyInstaller编译时mysql.connector在“except”中出现bug?

5 投票
2 回答
2546 浏览
提问于 2025-04-18 06:33

我有一个用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

生成的代码应该包含 tryexcept 这两个部分,但在判断程序实际需要哪些模块时,只会评估其中一个分支。

这可能会导致动态加载时出现各种问题。

一个简单的解决办法是直接包含所有相关的导入,比如:

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()

撰写回答