Celery Django 运行 task 任务的时候 提示NotRegistered
发布时间:2019-07-31T16:47:10:手机请访问
文章目录
Celery Django 运行 task 任务的时候 提示 NotRegistered
原来引入task 的方式是
1 2 |
from app01.utils.tasks import * |
但是老是提示 xxxtask NotRegistered,查询了好多的资料,终于解决了

因为是 Django 项目,所以在Celey 中需要引入制定的 task, 有人说 app.autodiscover_tasks()
可以自动导入,但是还是报错说 xxxtask 未被注册
方法一
所以我采用导入指定的 task 的方式:
1 2 3 4 5 |
CELERY_IMPORTS = ( # 指定导入的任务模块 'celery_app.task1', 'celery_app.task2' ) |
然后就不会报错了 : )
方法二
在 task 文件中 加入
1 2 3 |
from __future__ import absolute_import, unicode_literals from celery import shared_task |
使用绝对了路径进行导入
找到相关的原因了,是相对路径和绝对路径的问题
自动命名和相对导入
"相对导入"和"自动名称生成"在一起工作的不是很好,所以如果你使用了"相对导入",就需要显式地指明名字。
比如,如果客户端导入模块"myapp.tasks"作为".tasks",然后worker导入模块作为“myapp.tasks”,这样自动生成的名字就不能够正确匹配,worker就会抛出一个 NotRegistered
异常。
同样的情况在Django中也会发生,当你在INSTALLED_APPS中使用了"project.myapp"形式的名字:
1 2 |
INSTALLED_APPS = ['project.myapp'] |
如果你的app安装在project.myapp下,这样你的tasks模块将会以"project.myapp.tasks"形式导入,所以你必须保证总是以同样的名字导入tasks:
1 2 3 4 |
>>> from project.myapp.tasks import mytask # << GOOD >>> from myapp.tasks import mytask # << BAD!!! |
下面是第二个例子,client和worker以不同的名称导入了tasks模块进而造成了task被命名为不同的名字:
1 2 3 4 5 6 7 8 |
>>> from project.myapp.tasks import mytask >>> mytask.name 'project.myapp.tasks.mytask' >>> from myapp.tasks import mytask >>> mytask.name 'myapp.tasks.mytask' |
基于以上原因,你必须以相同的方式导入模块,这在python中也是一个好的实践。
相似地,你不要使用老的相对导入方式:
1 2 3 4 |
from module import foo # BAD! from proj.module import foo # GOOD! |
新的相对导入方式是可以的:
1 2 |
from .module import foo # GOOD! |
如果你正在使用的Celery工程中已经广泛使用了这样的导入方式,你也没有时间重构这些代码,那么你可以考虑显式地指定任务的名称而不是依赖于自动命名:
1 2 3 4 |
@task(name='proj.tasks.add') def add(x, y): return x + y |
