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

Flask后端使用SQLAlchemy连接MySQL出现连接异常问题求助

问题分析与解决方案

核心错误原因

你的代码中连接池的creator函数逻辑错误:lambda : conn会让连接池每次获取连接时都返回同一个固定的连接对象,而非创建新连接。这导致所有请求共用单一连接,一旦该连接被MySQL服务器超时断开,或被连接池回收关闭,后续请求再使用就会触发InterfaceError(0, '')或Already closed错误。

另外,你在事务块(with engine.begin())外部调用cursor的fetchone()/fetchall(),可能导致连接归还后cursor失效,引发潜在异常。

修复步骤

1. 修正连接池的creator函数

将创建新连接的逻辑放入creator函数中,确保每次调用都生成独立的新连接:

def createSQLConnection():
    # 定义每次创建新连接的函数
    def get_new_connection():
        connector = Connector()
        try:
            conn = connector.connect(
                "<Instance connection name>",
                "pymysql",
                user="...",
                password="...",
                db="...",
                ip_type=IPTypes.PUBLIC
            )
            return conn
        except Exception as e:
            connector.close()
            raise e

    engine = sqlalchemy.create_engine(
        "mysql+pymysql://",
        creator=get_new_connection,
        pool_size=140,
        max_overflow=50,
        pool_recycle=1800,
        # 启用连接预检查,自动丢弃失效连接
        pool_pre_ping=True
    )
    return engine

engine = createSQLConnection()

2. 启用连接预检查

添加pool_pre_ping=True参数,SQLAlchemy会在从连接池取出连接前自动发送测试查询(如SELECT 1),若连接已失效则自动丢弃并创建新连接,避免使用已关闭的连接。

3. 调整查询代码:在事务块内完成结果获取

将fetchone()/fetchall()操作放在with engine.begin()块内部,避免连接归还后cursor失效:

def rec_topic_wise(user_id):
    print("rec_topic_wise")

    # 获取用户数据
    try:   
        with engine.begin() as mydb:
            sql_result = mydb.execute(text("SELECT repr FROM users WHERE uid = :uid"), {"uid": user_id})
            row = sql_result.fetchone()
        if not row:
            return "null"
        user_representation = tensor(np.frombuffer(row[0]))
    except Exception as e:
        print(f"User query error: {e}")
        return "null"

    # 获取所有话题数据
    query = "SELECT id, repr FROM topics"
    try:
        with engine.begin() as mydb:
            sql_result = mydb.execute(text(query))
            res = sql_result.fetchall()
    except Exception as e:
        print(f"Topics query error: {e}")
        return "null"

    # 后续逻辑...

4. 确认MySQL服务器超时配置

确保SQLAlchemy的pool_recycle值(当前1800秒,即30分钟)小于MySQL服务器的wait_timeout和interactive_timeout值,避免连接被服务器主动断开后仍被连接池复用。

内容的提问来源于stack exchange,提问作者MilosPolo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:17:03