使用Flask和Flask-SQLAlchemy的Celery无法更新数据库记录

时间:2017-07-11 13:03:48

标签: python flask sqlalchemy celery flask-sqlalchemy

我正在使用Flask和Flask-SQLAlchemy创建背景芹菜任务来更新数据库记录的属性。我使用recommended documentation作为celery配置,这是我的代码的简化版本:

from flask import Flask
from celery import Celery

def make_celery(app):
    celery = Celery(app.import_name, broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery


app = Flask(__name__)

celery = make_celery(app)

class Stuff(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    processed = db.Column(db.Boolean)


@celery.task()
def process_stuff(stuff_id):
    stuff = Stuff.query.get(stuff_id)
    print("stuff.processed 1: {}".format(stuff.processed))
    stuff.processed = True
    print("stuff.processed 2: {}".format(stuff.processed))
    db.session.add(stuff)
    db.session.commit()
    print("stuff.processed 3: {}".format(stuff.processed))

@app.route("/process_stuff/<id>")
def do_process_stuff(id):
    stuff = Stuff.query.get_or_404(id)
    process_stuff.delay(stuff.id)
    return redirect(url_for("now_wait"))

这是打印语句的输出:

[2017-07-11 07:32:01,281: WARNING/PoolWorker-4] stuff.processed 1: False
[2017-07-11 07:32:01,282: WARNING/PoolWorker-4] stuff.processed 2: False
[2017-07-11 07:32:01,285: WARNING/PoolWorker-4] stuff.processed 3: False

我可以在我的芹菜工人日志中看到任务正在被接收和完成;但是,打印语句显示stuff.processed属性总是错误 - 即使我手动更新后,print语句也永远不会显示True(我已经在芹菜之外对此进行了测试,我可以更新属性)

有一个非常类似的问题here,但该解决方案对我的情况不起作用

图书馆版本

  • 烧瓶0.12.2
  • SQLAlchemy 1.1.11
  • Celery 4.0.2
  • Flask-SQLAlchemy 2.2

更新

其他测试显示我可以创建新的对象并将其持久保存到数据库中 - 更新预先存在的对象仍然会失败。

1 个答案:

答案 0 :(得分:1)

在我的问题中,我大大简化了代码,在这样做的时候,我将reserved属性更改为processed。我的实际模型看起来更像是这样:

class Stuff(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    reserved = db.Column(db.Boolean)

事实证明reserved是芹菜中的一个功能,这就是为什么无法从我的芹菜任务更新属性的原因。解决方案是重命名模型上的reserved属性。