我有一个Flask应用程序来启动长期运行的Celery任务(约10-120分钟/任务,有时候查询速度慢)。我使用Flask-SQLAlchemy进行ORM和连接管理。我的应用程序如下所示:
app = Flask(__name__)
db = SQLAlchemy(app)
celery = make_celery(app)
@app.route('/start_job')
def start_job():
task = job.delay()
return 'Async job started', 202
@celery.task(bind=True)
def job(self):
db.session.query(... something ...)
... do something for hours ...
db.session.add(... something ...)
db.session.commit()
return
不幸的是,我必须使用的MySQL服务器喜欢在几分钟不活动后关闭连接并且芹菜任务无法处理这种情况,所以经过很多等待后我得到了(2006年,'MySQL服务器已经消失')错误。连接池的AFAIK应该处理关闭的连接。我读了docs,但它只写了SQLALCHEMY_POOL_TIMEOUT
和SQLALCHEMY_POOL_RECYCLE
参数,所以基于一些随机互联网文章,我试图将回收更改为3分钟,但这没有帮助
连接(会话?)处理如何与此配置一起使用?我该怎么做才能避免这种错误?
答案 0 :(得分:1)
我不完全确定下面解决方案的优点,但似乎解决了这个问题。
会话在第一个查询(或插入)语句之前初始化连接并启动事务。然后它等待回滚或提交,但由于不活动,MySQL服务器在几分钟后关闭连接。解决方案是在很长一段时间内不需要它时关闭会话,SQLAlchemy将为下一个事务打开一个新会话。
@celery.task(bind=True)
def job(self):
db.session.query(... something ...)
db.session.close()
... do something for hours ...
db.session.add(... something ...)
db.session.commit()
return