我正在尝试将一组 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)
那么,如何在蓝图中但在请求之外获取应用程序上下文?
我通过以下更改解决了这个问题。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)
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |