2017-07-11 233 views
2

我用烧瓶和烧瓶SQLAlchemy创建背景芹菜任务来更新数据库记录的属性。我现在用的是recommended documentation对芹菜的配置,这是我的代码的简化版本:带烧瓶和烧瓶SQLAlchemy的芹菜不能更新数据库记录

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
  • 芹菜4.0 .2
  • Flask-SQLAlchemy 2.2

更新

附加测试表明我可以创建和坚持新创建的对象的数据库 - 更新预先存在的对象仍然失败。

+0

尝试添加方法'高清on_success(个体经营,RETVAL,TASK_ID,ARGS,kwargs): db.session.commit()''到ContextTask' –

+0

@DanilaGanchar没有运气不幸 – Anconia

+0

您可以加入烧瓶,芹菜,SQLAlchemy的问题的版本?顺便说一句,我不能重复你的行为。 –

回答

0

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

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

事实证明,reserved是芹菜的功能,这就是为什么物业不能从我的芹菜任务进行更新。解决方案是重命名模型上的reserved属性。