PyQt5调用mysql.connector.connect()崩溃,单独运行正常的原因排查
使用Python 3.13.1开发带PyQt5 GUI的待办应用,通过mysql-connector-python连接MySQL数据库。运行main.py时程序直接崩溃,无窗口弹出,错误码为-1073741819(0xC0000005),崩溃发生在TasksData构造函数调用mysql.connector.connect()的语句处。
关键情况
- 数据库正常,单独运行
tasks_data.py创建TasksData对象并调用方法时,数据库连接及功能均正常; - 仅运行
main.py(初始化MainWindow并创建TasksData)时崩溃,发生在窗口显示前的初始化阶段; - 尝试用
try-except捕获异常但无效,程序直接崩溃; - 已尝试更换解释器、重建虚拟环境,未解决;
- 使用的Python版本为3.13.1,解释器路径正确,已安装
mysql-connector-python==9.3.0; - 怀疑是导入问题或
mysql-connector-python与Python3.13兼容性问题,但无官方确认。
附相关代码(main.py、main_window.py、tasks_data.py),此前调试时会跳转至parse.py显示错误,此次无该现象。
核心疑问:为何在PyQt5应用内调用mysql.connector.connect()会崩溃,单独运行却正常?错误0xC0000005的原因是什么?
错误0xC0000005的本质
这个错误码是Windows系统的访问违规(Access Violation),意味着程序尝试访问了不被允许的内存地址(比如空指针、已释放内存、无权限的内存区域)。这类崩溃属于底层C扩展层面的错误,Python的try-except无法捕获,因为它发生在Python解释器之外的二进制代码中。
为何PyQt5环境下崩溃、单独运行正常?
Python 3.13与mysql-connector-python的兼容性问题
Python 3.13是较新版本,mysql-connector-python==9.3.0可能未完全适配其底层API变化。单独运行tasks_data.py时,程序执行路径简单,未触发兼容性冲突;但在PyQt5的GUI事件循环初始化环境中,解释器的内存布局、模块加载顺序发生变化,触发了C扩展中的内存访问bug。模块加载顺序与冲突
PyQt5会提前加载大量Qt的C++库,这些库可能与mysql-connector-python的C扩展模块(比如_mysql_connector.dll)存在内存管理或符号冲突。单独运行时没有Qt库的干扰,因此不会触发崩溃。GUI线程与数据库连接的冲突
PyQt5的主线程是GUI线程,若在主线程初始化阶段(窗口显示前)直接调用mysql.connector.connect(),可能会因为数据库连接的底层IO操作与GUI线程的事件循环初始化发生资源竞争,导致内存访问异常。而单独运行时无GUI线程的资源竞争,因此正常。
可行的解决办法
- 降级Python版本:暂时切换到Python 3.12.x版本,该版本与
mysql-connector-python==9.3.0的兼容性经过更多验证,大概率能解决崩溃问题。 - 更换数据库连接库:改用
pymysql(纯Python实现的MySQL客户端)替代mysql-connector-python,纯Python库不会触发底层C扩展的内存访问错误,且兼容性更好。安装命令:pip install pymysql,代码中只需将import mysql.connector替换为import pymysql,连接方式基本一致。 - 将数据库连接移至子线程:在PyQt5中,把
TasksData的初始化和数据库连接操作放到单独的工作线程中,避免在GUI主线程中执行底层IO操作。可以使用QThread实现,确保GUI线程与数据库操作线程分离。 - 升级/降级mysql-connector-python:尝试安装
mysql-connector-python的更早版本(比如8.3.0)或等待官方推出适配Python 3.13的新版本,看是否能解决兼容性问题。
内容的提问来源于stack exchange,提问作者панимаю

