从烧瓶视图中推送芹菜任务分离 SQLAlchemy 实例(DetachedInstanceError)

pushing celery task from flask view detach SQLAlchemy instances (DetachedInstanceError)

我正在使用 SQLAlchemy 模型(源自 sqlalchemy.ext.declarative.declarative_base)和 Flask-SQLAlchemy

当我尝试 运行 任何 celery 任务(只是空的)

@celery.task()
def empty_task():
    pass

在常见的烧瓶视图中

@blueprint.route(...)
def view():
   image = Image(...)
   db.session.add(image)
   db.session.flush()

   #this cause later error
   empty_task()

   #now accessing attributes ends with DetachedInstanceError
   return jsonify({'name': image.name, ...}

我得到

DetachedInstanceError: Instance <Image at 0x7f6d67e37b50> is not bound to a Session; attribute refresh operation cannot proceed

当我在任务推送后尝试访问模型时。没有任务它工作正常。如何解决?

更新: celery 使用这个任务库:

TaskBase = celery.Task
class ContextTask(TaskBase):
    abstract = True

    def __call__(self, *args, **kwargs):
        with app.app_context():
            try:
                return TaskBase.__call__(self, *args, **kwargs)
            except Exception:
                sentry.captureException()
                raise

celery.Task = ContextTask

啊我在 运行 任务中的错误。它应该是 empty_task.apply_async()

直接调用它会创建带有新会话的新应用上下文,从而导致旧会话关闭。

今天我在 运行 鼻子测试时遇到了同样的问题。

DetachedInstanceError: Instance <EdTests at 0x1071c4790> is not bound to a Session; attribute refresh operation cannot proceed

我正在使用 Celery 和 Flask SQLAlchemy。 问题是在我更改测试设置时引起的:

CELERY_ALWAYS_EAGER = True

我发现当 运行 celery 任务同步时,db session 在任务结束时关闭。

我按照 Celery's documentation 用户指南解决了我的问题。 Celery 建议不要启用任务的急切测试。