我正在尝试将Flask应用程序集合转换为包含多个蓝图的单个应用程序。
在我的一个应用程序中,我有一个在后台定期运行的任务,与请求无关。它看起来像这样:
import apscheduler.schedulers.background
import flask
app = flask.Flask(__name__)
app.config['DATABASE']
scheduler = apscheduler.schedulers.background.BackgroundScheduler()
scheduler.start()
def db():
_db = flask.g.get('_db')
if _db is None:
_db = get_db_connection_somehow(app.config['DATABASE'])
flask.g._db = _db
return _db
@scheduler.scheduled_job('interval', hours=1)
def do_a_thing():
with app.app_context():
db().do_a_thing()
当我将此应用程序转换为蓝图时,我无法访问应用程序对象,并且在我需要时无法弄清楚如何创建应用程序上下文。这就是我试过的:
import apscheduler.schedulers.background
import flask
bp = flask.Blueprint('my_blueprint', __name__)
scheduler = apscheduler.schedulers.background.BackgroundScheduler()
scheduler.start()
def db():
_db = flask.g.get('_db')
if _db is None:
_db = get_db_connection_somehow(flask.current_app.config['DATABASE'])
flask.g._db = _db
return _db
@bp.record
def record(state):
with state.app.app_context():
flask.g._app = state.app
@scheduler.scheduled_job('interval', hours=1)
def do_a_thing():
with flask.g._app.app_context():
db().do_a_thing()
我得到的错误是:
RuntimeError: Working outside of application context.
那么,如何在蓝图中但在请求之外获取应用程序上下文?
答案 0 :(得分:2)
我通过以下更改解决了这个问题。首先,我在Flask应用程序上设置了scheduler
对象:
app = flask.Flask(__name__)
app.scheduler = apscheduler.schedulers.background.BackgroundScheduler()
app.scheduler.start()
接下来,我更改了运行后台任务的函数以接受app
作为参数,因此我可以从app.config
读取数据库连接信息:
def do_a_thing(app: flask.Flask):
db = get_db_connection_somehow(app.config['DATABASE'])
db.do_a_thing()
最后,我在Blueprint.record()
中设置了预定作业:
@bp.record
def record(state):
state.app.scheduler.add_job(do_a_thing, trigger='interval', args=[state.app], hours=1)