flask-apscheduler的app_context问题
2018-05-12 本文已影响38人
Kant_14
在flask应用中处理定时任务,有不少好用的模块,其中一个是apscheduler。apscheduler虽好用,但比较容易碰到找不到上下文环境的问题。一般的例子,总是把任务函数写在app创建的同一个文件中,从而避免这个问题,但在现实中,我们一般还是希望单独放一个文件,方便管理。
如果把任务函数单独放一个文件,调用flask的current_app是无效的,一般采用的方式是,在任务函数中临时调用app创建函数,生成一个新的应用,并使用这个新应用的上下文环境。比如说:
from app import create_app
def shcduler_job1():
app = create_app(args)
with app.app_context:
do the job
这是一个可行的解决方案,不过如果任务数较多,或者任务间隔比较短,就会导致app被大量创建的问题,伴随产生的是诸如文件调用次数过多、数据库session数超出等问题。那么,我们就考虑,能不能使用一个单独的app对象,作为定时任务的固定环境,避免每次都创建一个。比如说:
from app import create_app
APP = create_app(args)
def shcduler_job1():
global APP
with APP.app_context:
do the job
直接这样写是有问题的,因为定时任务模块会在应用创建的时候,也就是create_app()函数中被引入,所以这样写会导致循环问题,因此,APP的初始化工作应该被滞后到执行函数的时候,于是修改代码:
from app import create_app
APP = None
def get_app():
global APP
APP = APP if APP is not None else create_app(args)
def shcduler_job1():
get_app()
with APP.app_context:
do the job
这个方案虽然似乎能够运行,但终究是极为丑陋的,也因此放出来,希望有思路或者有经验的同仁多指教。