You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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 提供的命令行工具:

  1. 设置环境变量:
    # Linux/macOS
    export FLASK_APP=app.py
    # Windows
    set FLASK_APP=app.py
    
  2. 启动 Worker:
    flask rq worker
    

这种方式会自动加载 Flask app 上下文和任务定义,避免找不到任务的问题。

为什么任务会被移到失败队列?

当 Worker 尝试执行任务时,找不到对应的任务函数定义(比如任务未正确注册、Worker 未加载到任务代码),就会把任务移至失败队列。解决上面的注册和上下文问题后,这个情况会随之消失。

内容的提问来源于stack exchange,提问作者Mohamed Okasha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:48:27