Flask使用rq-scheduler报错:处于应用上下文之外
Flask后台RQ任务无法访问应用上下文的解决办法
问题根因
logging_test方法在create_app的app.app_context()上下文块内执行,此时Flask应用上下文处于激活状态,所以能正常访问current_app。data_sync是RQ调度的后台任务,执行时运行在独立的Worker进程中,和主Flask进程的上下文完全隔离,直接调用current_app就会触发RuntimeError。
可行解决方案
方案1:给Sync类传入应用实例,任务内手动激活上下文
修改app/data/sync.py:
from flask import current_app from time import sleep import logging class Sync(): def __init__(self, app): self.app = app # 同步日志配置和主应用一致 logging.basicConfig(filename="tasks.log", level=logging.INFO, format=f'%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s') def logging_test(self): current_app.logger.info("this is running fine") def data_sync(self): with self.app.app_context(): current_app.logger.info("Start sync") print("task") sleep(2) print("another task") current_app.logger.info("End sync")
然后在app/__init__.py创建Sync实例时传入app:
# ... 其他代码 sync = Sync(app=app) # ... 其他代码
方案2:任务内直接初始化应用并激活上下文
如果项目用了应用工厂模式,也可以在任务里直接调用create_app()生成应用实例:
修改app/data/sync.py:
from time import sleep from app import create_app class Sync(): def logging_test(self): from flask import current_app current_app.logger.info("this is running fine") def data_sync(self): app = create_app() with app.app_context(): app.logger.info("Start sync") print("task") sleep(2) print("another task") app.logger.info("End sync")
核心提示
Flask的current_app是进程局部变量,只有在激活的应用上下文里才能访问。RQ Worker是独立进程,不会继承主进程的上下文,所以必须在任务内部手动创建并激活上下文。
内容的提问来源于stack exchange,提问作者Hamilton
相关产品推荐
相关产品推荐

