gpt4 book ai didi

python - Flask - 不受当前上下文的限制

转载 作者:太空宇宙 更新时间:2023-11-03 15:01:22 24 4
gpt4 key购买 nike

我正在尝试编写一个类 ChangeBackStatusOnErrorTask ,它的功能正如其名称所暗示的那样。

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 未绑定(bind)到我的 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

如何解决这个问题?

最佳答案

我假设您使用 sqlachemy 和flask-sqlalchemy 扩展。并且您从某个专用模块获取 db 对象,并且该对象也绑定(bind)到 Flask 实例(请编辑您的问题以澄清这些点)。

在您的 app 模块中声明您的 celery 配置:

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

然后在你的 celery 模块中,你需要将它绑定(bind)到 Flask:

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 创建的对象来装饰您的任务:

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

来源:flask doc

关于python - Flask - 不受当前上下文的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45067618/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com