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

Wil*_*son 6 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()
Run Code Online (Sandbox Code Playgroud)

当我将此应用程序转换为蓝图时,我无法访问应用程序对象,并且无法弄清楚如何在需要时创建应用程序上下文。这是我尝试过的:

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()
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

RuntimeError: Working outside of application context.
Run Code Online (Sandbox Code Playgroud)

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

Wil*_*son 5

我通过以下更改解决了这个问题。scheduler首先,我在 Flask 应用程序上设置一个对象:

app = flask.Flask(__name__)
app.scheduler = apscheduler.schedulers.background.BackgroundScheduler()
app.scheduler.start()
Run Code Online (Sandbox Code Playgroud)

接下来,我更改了运行后台任务的函数以接受作为app参数,因此我可以从中读取数据库连接信息app.config

def do_a_thing(app: flask.Flask):
    db = get_db_connection_somehow(app.config['DATABASE'])
    db.do_a_thing()
Run Code Online (Sandbox Code Playgroud)

最后,我在以下位置设置了预定作业Blueprint.record()

@bp.record
def record(state):
    state.app.scheduler.add_job(do_a_thing, trigger='interval', args=[state.app], hours=1)
Run Code Online (Sandbox Code Playgroud)