pymysql中Cursor.execute未执行 程序运行至该行停止问题求助
问题根因
三个核心问题叠加导致程序无报错静默终止:
- 跨驱动混用不兼容类:使用pymysql创建连接时,传入了属于MySQLdb驱动的
MySQLdb.cursors.DictCursor作为游标类。两个MySQL驱动的内部实现、实例结构完全不兼容,调用cursor.execute()时会触发C层面的内存访问错误(段错误),这类错误属于操作系统直接终止进程的级别,Python解释器的异常捕获机制完全无法拦截,因此不会进入你写的pymysql.Error捕获分支,也不会抛出任何Python层报错,进程直接退出。 - 异常捕获逻辑完全失效:代码中捕获
pymysql.Error后直接pass无任何处理,就算是pymysql本身抛出的连接失败、权限不足、SQL语法错误,也会被直接吞掉,没有任何日志输出,完全阻断问题排查路径。 - 单例长连接存在隐性失效风险:单例模式持有的长连接如果闲置时间超过MySQL服务端配置的
wait_timeout阈值,会被服务端主动断开,拿到失效连接执行操作时也可能触发无日志的阻塞或崩溃,该问题为次要诱因,你当前场景的核心触发点为跨驱动传参。
修复方案
按优先级依次调整:
- 统一驱动依赖,移除跨驱动类引用
如果你确定使用pymysql作为操作驱动,就将游标类替换为pymysql自带的字典游标,不要引入MySQLdb的任何类:import pymysql from pymysql.cursors import DictCursor # 连接配置示例 conn = pymysql.connect( host="127.0.0.1", user="nicolacivile", password="12345", db="ildb", cursorclass=DictCursor # 必须使用当前驱动下的对应游标类 ) - 修正异常捕获逻辑,禁止裸吞错误
捕获到数据库异常时必须打印完整错误栈,禁止直接pass,异常处理后向上抛出阻断错误流程,避免带着无效状态继续执行:import traceback try: conn = pymysql.connect(/* 你的连接参数 */) except pymysql.Error as e: print(f"数据库连接异常:{str(e)}") traceback.print_exc() raise - 给单例连接增加连通性校验
每次从工厂类获取连接时,先通过ping校验连接有效性,失效连接自动重连,避免使用已被服务端断开的死连接:def get_connection(self): if self._instance_conn is not None: try: # reconnect=True表示连接断开时自动尝试重连 self._instance_conn.ping(reconnect=True) return self._instance_conn except Exception: self._instance_conn = None # 走新建连接逻辑 self._instance_conn = pymysql.connect(/* 你的连接参数 */) return self._instance_conn - 规范化SQL执行逻辑
确认查询语句使用pymysql要求的%s作为参数占位符,禁止直接拼接SQL字符串,执行时参数以元组形式传入,避免语法错误或SQL注入风险:# 查询语句示例,确保带未删除标记的过滤条件 SELECT_ANNWEBSERVER_PK_QUERY = """ SELECT * FROM annotation_web_server WHERE idAnnotationWebServer = %s AND is_deleted = 0 """ def getAnnWebServer(self, ann_id): conn = self.get_connection() cursor = conn.cursor() print(f"after cursor {ann_id}") # 参数用元组传入,即使单参数也要加逗号标识为元组 cursor.execute(SELECT_ANNWEBSERVER_PK_QUERY, (ann_id,)) print("execute finished") result = cursor.fetchall() cursor.close() return result
内容的提问来源于stack exchange,提问作者zabitstack
相关产品推荐
相关产品推荐

