Python中如何解决flask_sqlalchemy的MySQL server has gone away (BrokenPipeError)错误

这个问题有大佬碰到过么?不知道怎么解决,网上搜了 SQLALCHEMY_POOL_SIZE,SQLALCHEMY_POOL_RECYCLE 这两个参数设定的方案也不成功。现在不太清楚怎么解决。而且也不明白什么原因导致的问题。
Python中如何解决flask_sqlalchemy的MySQL server has gone away (BrokenPipeError)错误

13 回复

这个表示 mysql 连接已经断开了,SQLALCHEMY_POOL_RECYCLE 设置短一些,或者不使用连接池,去掉 SQLALCHEMY_POOL_SIZE 和 SQLALCHEMY_POOL_RECYCLE


这个错误通常发生在数据库连接闲置超时后被服务器关闭。Flask-SQLAlchemy的默认连接池可能持有这些失效的连接,导致后续操作失败。

核心解决方案是配置SQLAlchemy的连接池回收机制,让它在使用前自动检查并重置失效连接。在你的Flask应用配置中加入以下设置:

app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    'pool_recycle': 300,  # 小于MySQL的wait_timeout(默认28800秒)
    'pool_pre_ping': True,  # 关键设置:执行前验证连接
}

如果问题依然存在,可以尝试更激进的配置:

app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    'pool_recycle': 280,
    'pool_pre_ping': True,
    'pool_size': 10,
    'max_overflow': 20,
    'pool_timeout': 30,
}

对于长时间运行的任务,建议在操作前显式检查连接:

from sqlalchemy import text

@app.route('/long-task')
def long_task():
    try:
        # 测试连接是否有效
        db.session.execute(text('SELECT 1'))
    except:
        db.session.remove()  # 清除当前会话
        db.session.begin()   # 开始新会话
    
    # 继续你的业务逻辑
    result = YourModel.query.filter_by(...).all()
    return jsonify([item.to_dict() for item in result])

总结:启用pool_pre_ping是最直接的解决方案。

这要看 mysql 的 error.log 来确定问题,你改 sqlalchemy 那俩参数似乎并无根据呀?

我原来没有设置出了问题,然后才加的,加了也没用。

这样啊,那我去找找看 mysql 的日志。

session 泄露没有关闭吧,用 try catch 加上下文管理器试试?

session 每个请求内用完都要关掉么?

#6 有些版本的 sqlalchemy session 池管理有问题,用完关掉不是很影响效率,而且能解决报错的问题。

我是每次用完 session 关掉,才完全解决这个问题的。



其实大家不用猜了。python 的几乎所有库的连接池都有问题

原因很简单,连接池应该在一定超时时间 idle 之后去自动重连一个的。python 的 threading、协程的状况,几乎没有一个库去实现一个 timer 主动去轮换连接。都是一个 db 操作的动作再去检查连接。然后远端主动关闭,python 的 tcp 其实是没法响应 TIME_WAIT 的。于是一发过去就 Broken pipe。。

那应该咋解决?就是有那种好久没人使用的系统,一来又一顿猛着用那种

几行代码
就能搞定的事情

db.session.close()

每次都关掉,绝对会解决

回到顶部