Celery Django 运行 task 任务的时候 提示NotRegistered

Celery Django 运行 task 任务的时候 提示 NotRegistered

原来引入task 的方式是

Python
from app01.utils.tasks import *
1
2
from app01 . utils . tasks import *
 

但是老是提示 xxxtask NotRegistered,查询了好多的资料,终于解决了

因为是 Django 项目,所以在Celey 中需要引入制定的 task, 有人说 app.autodiscover_tasks() 可以自动导入,但是还是报错说 xxxtask 未被注册

方法一

所以我采用导入指定的 task 的方式:

Python
CELERY_IMPORTS = ( # 指定导入的任务模块 'celery_app.task1', 'celery_app.task2' )
1
2
3
4
5
CELERY_IMPORTS = (                                    # 指定导入的任务模块
     'celery_app.task1' ,
     'celery_app.task2'
)
 

然后就不会报错了 : )

方法二

在 task 文件中 加入

Python
from __future__ import absolute_import, unicode_literals from celery import shared_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"形式的名字:

Python
INSTALLED_APPS = ['project.myapp']
1
2
INSTALLED_APPS = [ 'project.myapp' ]
 

如果你的app安装在project.myapp下,这样你的tasks模块将会以"project.myapp.tasks"形式导入,所以你必须保证总是以同样的名字导入tasks:

Python
>>> from project.myapp.tasks import mytask # << GOOD >>> from myapp.tasks import mytask # << BAD!!!
1
2
3
4
>>> from project . myapp . tasks import mytask    # << GOOD
 
>>> from myapp . tasks import mytask      # << BAD!!!
 

下面是第二个例子,client和worker以不同的名称导入了tasks模块进而造成了task被命名为不同的名字:

Python
>>> from project.myapp.tasks import mytask >>> mytask.name 'project.myapp.tasks.mytask' >>> from myapp.tasks import mytask >>> mytask.name 'myapp.tasks.mytask'
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中也是一个好的实践。

相似地,你不要使用老的相对导入方式:

Python
from module import foo # BAD! from proj.module import foo # GOOD!
1
2
3
4
from module import foo    # BAD!
 
from proj . module import foo    # GOOD!
 

新的相对导入方式是可以的:

Python
from .module import foo # GOOD!
1
2
from . module import foo    # GOOD!
 

如果你正在使用的Celery工程中已经广泛使用了这样的导入方式,你也没有时间重构这些代码,那么你可以考虑显式地指定任务的名称而不是依赖于自动命名:

Python
@task(name='proj.tasks.add') def add(x, y): return x + y
1
2
3
4
@ task ( name = 'proj.tasks.add' )
def add ( x , y ) :
     return x + y
 



  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值