2017-07-11 4 views
2

Je crée une tâche de fond de céleri avec Flask et Flask-SQLAlchemy pour mettre à jour une propriété d'un enregistrement de base de données. J'utilise le recommended documentation pour la config de céleri et c'est une version simplifiée de mon code:Céleri avec Flask et Flask-SQLAlchemy ne peut pas mettre à jour un enregistrement de base de données

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")) 

Et c'est la sortie des états d'impression:

[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 

je peux voir dans mon travailleur de céleri enregistre que la tâche est en cours et terminée; cependant, les instructions d'impression montrent que la propriété stuff.processed est TOUJOURS Faux - l'instruction d'impression ne montre jamais Vrai même après que je l'ai mise à jour manuellement (j'ai testé cela en dehors de céleri et je peux mettre à jour la propriété très bien).

Il y a un problème très similaire here mais cette solution ne fonctionne pas pour ma situation

Versions Bibliothèque

  • Flask 0.12.2
  • SQLAlchemy 1.1.11
  • Céleri 4.0 .2
  • Flask-SQLAlchemy 2.2

Mise à jour

Des tests supplémentaires montre que je peux créer et persister des objets nouvellement créés à la base de données - mise à jour des objets préexistants continuent d'échouer.

+0

essayez d'ajouter la méthode 'def on_success (auto, RETVAL, task_id, args, kwargs): db.session.commit()' 'à ContextTask' –

+0

@DanilaGanchar pas de chance, malheureusement, – Anconia

+0

pourriez-vous ajouter flacon, le céleri, sqlalchemy versions à la question? d'ailleurs je ne peux pas répéter votre comportement. –

Répondre

0

Dans ma question, j'ai simplifié le code sensiblement et, ce faisant, j'ai changé la propriété reserved à processed. Mon modèle actuel ressemble plus à ceci:

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

Il se avère que reserved est une fonction dans le céleri, ce qui explique pourquoi la propriété n'a pas pu être mis à jour de ma tâche de céleri. La solution consistait à renommer la propriété reserved sur le modèle.