在Heroku中使用flask-rq2扩展执行任务时遇AttributeError问题求助
解决 Flask-RQ2 中 AttributeError: module 'app' has no attribute 'task' 的问题
你遇到的核心问题是任务没有被正确注册到 Flask-RQ2 实例中,导致调用 task.queue() 时找不到对应属性,最终任务被移至失败队列。下面一步步帮你排查和解决:
1. 正确定义并注册任务
Flask-RQ2 依赖 @rq.task 装饰器标记任务函数,只有被装饰的函数才会被注册到 RQ 实例,才能调用 .queue() 方法入队。
正确代码结构示例
from flask import Flask from flask_rq2 import RQ import os # 初始化 Flask 应用 app = Flask(__name__, template_folder='templates') app.config['RQ_REDIS_URL'] = os.environ['REDIS_URL'] # 初始化 RQ 实例 rq = RQ(app) # 用 @rq.task 装饰器定义你的任务 @rq.task def my_custom_task(arg1): """这里编写任务的具体逻辑""" result = f"处理参数: {arg1}" print(result) return result
2. 正确调用任务入队
你需要调用被装饰后的任务函数的 .queue() 方法,而非一个不存在的 task.queue():
# 错误写法(导致你遇到的 AttributeError) # job = task.queue(arg1) # 正确写法:使用你定义的任务函数 job = my_custom_task.queue("你的参数内容")
3. 确保在 Flask 上下文环境中操作
不管是入队任务还是启动 Worker,都需要在 Flask app 的上下文环境中执行:
- 如果在视图函数中触发任务:
@app.route('/trigger-task') def trigger_task(): job = my_custom_task.queue("来自视图的参数") return f"任务已入队,ID: {job.id}" - 如果在脚本中手动测试:
if __name__ == '__main__': with app.app_context(): # 入队任务 job = my_custom_task.queue("测试参数") print(f"任务 ID: {job.id}") # 启动 Worker(burst=True 表示执行完队列任务后退出) worker = rq.get_worker() worker.work(burst=True)
4. 推荐用命令行启动 Worker
手动调用 default_worker.work() 容易出现上下文问题,更稳妥的方式是用 Flask-RQ2 提供的命令行工具:
- 设置环境变量:
# Linux/macOS export FLASK_APP=app.py # Windows set FLASK_APP=app.py - 启动 Worker:
flask rq worker
这种方式会自动加载 Flask app 上下文和任务定义,避免找不到任务的问题。
为什么任务会被移到失败队列?
当 Worker 尝试执行任务时,找不到对应的任务函数定义(比如任务未正确注册、Worker 未加载到任务代码),就会把任务移至失败队列。解决上面的注册和上下文问题后,这个情况会随之消失。
内容的提问来源于stack exchange,提问作者Mohamed Okasha
相关产品推荐
相关产品推荐

