如何在蓝图中获取应用程序上下文,但不在请求中?

时间:2017-08-09 20:45:11

标签: python flask

我正在尝试将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.

那么,如何在蓝图中但在请求之外获取应用程序上下文?

1 个答案:

答案 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)