2017-07-12 9 views
0

私は、その名前が示すとおり正確に行うクラスChangeBackStatusOnErrorTaskを作成しようとしています。 Flask - 現在のコンテキストに限定されていません

File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/celery/app/trace.py", line 367, in trace_task 
    R = retval = fun(*args, **kwargs) 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/celery/app/trace.py", line 622, in __protected_call__ 
    return self.run(*args, **kwargs) 
    File "/Users/vng/Dropbox/Code/Affiliate/AutomataHeroku/automata/server/tasks.py", line 59, in deploy_server 
    server = Server.query.get(server_id) 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 498, in __get__ 
    return type.query_class(mapper, session=self.sa.session()) 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 78, in __call__ 
    return self.registry() 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/sqlalchemy/util/_collections.py", line 990, in __call__ 
    return self.registry.setdefault(key, self.createfunc()) 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2861, in __call__ 
    return self.class_(**local_kw) 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 143, in __init__ 
    self.app = app = db.get_app() 
    File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 957, in get_app 
    'application not registered on db instance and no application' 
RuntimeError: application not registered on db instance and no application bound to current context 

がどのように私はこの問題を解決することができます

class ChangeBackStatusOnErrorTask(Task): 
    abstract = True 

    def on_failure(self, exc, task_id, args, kwargs, einfo): 
    server = Server.query.get(server_id) 
    server.status = RemoteStatus.ERROR 
    db.session.commit() 


@celery.task(bind=True, base=ChangeBackStatusOnErrorTask) 
def deploy_server(self, server_id): 
    try: 
    server.status = RemoteStatus.LAUNCHING 
    db.session.commit() 

    host = server.ssh_user + '@' + server.ip 
    execute(fabric_deploy_server, self, server, hosts=host) 

    server.status = RemoteStatus.LAUNCHED 
    db.session.commit() 
    except Exception as e: 
    server.status = RemoteStatus.ERROR 
    db.session.commit() 
    traceback.print_exc() 
    raise e 

しかし、このコードはChangeBackStatusOnErrorTaskが私のフラスココンテキストにバインドされていないという事実に起因して動作していませんか?

+0

アプリを作成しましたか?クラス定義の前に 'tasks.py'の' app = Flask(__ name __) 'を入力してください –

答えて

0

sqlachemyとflask-sqlalchemy拡張を使用すると仮定します。そして、あなたはdbオブジェクトをいくつかの専用モジュールから取得し、このオブジェクトもフラスコインスタンスにバインドされています(これらの点を明確にするために質問を編集してください)。あなたのappモジュール内部

は、あなたのセロリの設定を宣言:

from celery import Celery 
from app import current_app as app 

def bound_celery(app): 
    celery = Celery(
     app.import_name, 
     backend=app.config['CELERY_RESULT_BACKEND'],  
     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 

celery = bound_celery(app) 

そして最後に、あなたを飾るためにcelery作成したオブジェクトを使用します。

app = Flask(__name__) 
app.config[CELERY_BROKER_URL] = 'redis://localhost:6379' 
app.config[CELERY_RESULT_BACKEND] = 'redis://localhost:6379' 

は、その後、あなたのセロリモジュール内には、フラスコにそれをバインドする必要がありますタスク:

@celery.task(bind=True, base=ChangeBackStatusOnErrorTask) 
def deploy_server(self, server_id): 
    ... 

出典:flask doc

+0

私は現在あなたが言及したものとほとんど同じフラスコ・セロリーを使用しています:https://github.com/Robpol86/Flask-Celery- Helper/blob/master/flask_celery.py#L220 私はフラスコがすでにその面で私をカバーしていると思います。 – Sparrowcide

+0

[doc](http://flask.pocoo.org/docs/0.12/patterns/celery/)と[フラスコ - セロリ・レアリスム](https://github.com/ask/flask-celery/blob /master/README.rst)は、もはや拡張の必要はないと言っています。それを使用することは、もはやミドルウェアを維持しないことに依存する危険にさらされます。とにかく私の答えを見て、間違っている、間違ってバインドされたオブジェクトは 'セクシー'ではなく 'db'です。あなたは完全なコードを共有していただけますか?これで、dbオブジェクトがどのように作成され、共有されているかがわかります。 –

関連する問題