简体   繁体   English

使用Flask和SQLAlchemy在Celery任务中未更新数据库

[英]Database is not updated in Celery task with Flask and SQLAlchemy

I'm writing web application with Flask and SQLAlchemy. 我正在用Flask和SQLAlchemy编写Web应用程序。 My program needs to process some stuff in the background and then mark this stuff as processed in the database. 我的程序需要在后台处理一些东西,然后将此东西标记为在数据库中已处理。 Using standard Flask/Celery example , I have something like this: 使用标准的Flask / 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):
    # process stuff here

    stuff.processed = True
    db.session.commit()

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

I can access my database from process_stuff (eg submit queries like Stuff.query.get(some_id) work), but db.session.commit() do nothing: my stuff record is not updated. 我可以从process_stuff访问我的数据库(例如,提交诸如Stuff.query.get(some_id)工作之类的查询),但是db.session.commit()无济于事:我的stuff记录未更新。 According to Celery worker log, commit occures but nothing changes in the database. 根据Celery worker日志,提交已发生,但数据库中没有任何更改。 Is there something wrong with my db.session.commit() ? 我的db.session.commit()吗? Is it possible to make such commit somehow? 是否可以以某种方式做出这样的提交?

Okay, I got it. 知道了 stuff passed to process_stuff() is not attached to db.session . 传递给process_stuff() stuff未附加到db.session I have to make explicit request in process_stuff() to get the right stuff object like this: 我必须在process_stuff()进行显式请求,以获得正确的stuff对象,如下所示:

@celery.task()
def process_stuff(stuff):
    # process stuff here

    my_stuff = Stuff.query.get(stuff.id)

    my_stuff.processed = True
    db.session.commit()

Now it works. 现在可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM