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
相关产品推荐
相关产品推荐

