You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pymysql中Cursor.execute未执行 程序运行至该行停止问题求助

问题根因

三个核心问题叠加导致程序无报错静默终止:

  • 跨驱动混用不兼容类:使用pymysql创建连接时,传入了属于MySQLdb驱动的MySQLdb.cursors.DictCursor作为游标类。两个MySQL驱动的内部实现、实例结构完全不兼容,调用cursor.execute()时会触发C层面的内存访问错误(段错误),这类错误属于操作系统直接终止进程的级别,Python解释器的异常捕获机制完全无法拦截,因此不会进入你写的pymysql.Error捕获分支,也不会抛出任何Python层报错,进程直接退出。
  • 异常捕获逻辑完全失效:代码中捕获pymysql.Error后直接pass无任何处理,就算是pymysql本身抛出的连接失败、权限不足、SQL语法错误,也会被直接吞掉,没有任何日志输出,完全阻断问题排查路径。
  • 单例长连接存在隐性失效风险:单例模式持有的长连接如果闲置时间超过MySQL服务端配置的wait_timeout阈值,会被服务端主动断开,拿到失效连接执行操作时也可能触发无日志的阻塞或崩溃,该问题为次要诱因,你当前场景的核心触发点为跨驱动传参。
修复方案

按优先级依次调整:

  1. 统一驱动依赖,移除跨驱动类引用
    如果你确定使用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  # 必须使用当前驱动下的对应游标类
    )
    
  2. 修正异常捕获逻辑,禁止裸吞错误
    捕获到数据库异常时必须打印完整错误栈,禁止直接pass,异常处理后向上抛出阻断错误流程,避免带着无效状态继续执行:
    import traceback
    try:
        conn = pymysql.connect(/* 你的连接参数 */)
    except pymysql.Error as e:
        print(f"数据库连接异常:{str(e)}")
        traceback.print_exc()
        raise
    
  3. 给单例连接增加连通性校验
    每次从工厂类获取连接时,先通过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
    
  4. 规范化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:48:22