使用flask-sq与flask-sqlalchemy偶尔会引发ResourceClosedError

时间:2017-11-03 16:50:44

标签: python asynchronous sqlalchemy celery flask-sqlalchemy

最近,我使用flask-sq与flask-sqlalchemy对模型操作进行了一些异步任务。虽然它在调用模型方法时偶尔会引发ResourceClosedError错误。我不知道我的rq-worker发生了什么事情导致了这个问题。我无法正确重现该问题。这是片段。

worker.py

if __name__ == '__main__':
    with app.app_context():
        QUEUE = get_queue()
        worker = get_worker()
        worker.push_exc_handler(retry_handler)
        worker.work()

tasks.py (包含一些异步任务)

@job
def async_restart_task(task_id):
    creating_info = {"status": TaskStatus.Creating}
    task = TaskModel.update_task(task_id, creating_info)

    task = TaskModel.get_task_by_id(task_id)
    service = get_service(task.service)

    for jobs in iter_group(10, service.gen_jobs(task)):
        JobModel.add_jobs(jobs)

异步任务偶尔会引发ResourceClosedError

ResourceClosedError: This result object does not return rows. It has been closed automatically.

我不知道如何通过遵循良好做法来解决问题。我已经搜索了很长一段时间并遇到了同样的问题。参考:Celery and SQLAlchemy - This result object does not return rows. It has been closed automatically

在async-task中使用sqlalchemy是否有任何好的建议或示例?

1 个答案:

答案 0 :(得分:0)

我得到了一个很好的总结和建议来自the same questionmulti-processes用例中使用sqlalchemy喜欢使用flask-rq的代码。感谢sqlalchemy的作者@zzzeek给我一个很好的解释。

它告诉我们,当使用sqlalchemy通过共享多进程或工作者之间的连接时,很容易发生这个类问题。我们最好实例化一个新的engine来完成另一个进程的工作,比如分叉的子进程。

因此,当使用像celeryRQ这样的异步队列以及使用sqlalchemy的任何其他队列时。最好从原始JobTask类继承以设置新的enginesession来修复此问题。从same issue

开始

最后。您可以按照@zzzeek的一些建议或说明来参考sqlalchemy FAQ