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

时间:2015-05-20 10:33:12

标签: python flask sqlalchemy celery flask-sqlalchemy

我正在使用SQLAlchemy模型(从sqlalchemy.ext.declarative.declarative_base派生)和Flask-SQLAlchemy

当我尝试运行任何芹菜任务(只是空)

@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

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

更新: 芹菜使用这个任务库:

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

2 个答案:

答案 0 :(得分:2)

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

直接调用它会在新会话中创建新的应用程序上下文,导致关闭旧会话。

答案 1 :(得分:0)

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

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建议不要对任务进行热切的测试。