我正拼命想让Celery与Django很好地玩,但无济于事。我正在惹恼下面的事情:
项目/ settings.py:
...
import djcelery
djcelery.setup_loader()
BROKER_URL = 'django://'
CELERY_RESULT_BACKEND = 'django://'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ENABLE_UTC = True
...
应用程序/ tasks.py:
from celery.task import task
@task()
def scheduled_task(param1, param2):
...
return something
直接调用scheduled_task(param1, param2)
(没有装饰器)按预期工作。然而,当添加装饰器并启动'开发'芹菜工作时,就像这样:
python manage.py celery worker --loglevel=info
...我收到以下错误:
TypeError: 'module' object is not callable
我把它归结为@task
装饰者。我尝试的每个组合都失败了,包括:
from celery import task
from celery.task import task
from celery.task.base import task
@task
@task()
@task.task
@task.task()
@celery.task
@celery.task()
在异常中调用堆栈似乎没有任何区别,它们都出现以认为task
是一个模块,而不是可调用的!让事情更令人沮丧:
>>> from celery.task import task
>>> task
<function task at 0x10aa2a758>
这对我来说确实很可靠!知道可能会发生什么吗?如果我错过了任何内容,我很乐意发布其他日志,文件或澄清任何其他内容。
答案 0 :(得分:1)
(转换为评论的答案)
从stack trace开始,我认为行return backend(app=self, url=url)
是异常发生的地方。
所以无论backend
是什么,它似乎都不是可调用的。我会尝试通过在
celery/app/base.py
)中设置pdb断点
try:
backend(app=self, url=url)
except:
import pdb; pdb.set_trace(),
然后检查backend
,并向上移动堆栈(u
命令在pdb中,d
再次向下移动,w
以显示调用堆栈)以调试其中一切都错了。
celery docs也提到了这个:
如何导入任务装饰器?
任务装饰器在你的Celery实例上可用,如果你不知道那是什么,请阅读Celery的第一步。
如果您正在使用Django或仍在使用基于“旧”模块的celery API ,那么您可以像这样导入任务装饰器:
from celery import task
@task
def add(x, y):
return x + y
因此,应该清除任何关于导入任务装饰器的方法的错误是正确的。
答案 1 :(得分:0)
这是一个有点老问题,但我遇到了类似的麻烦,这对我有用:
项目/ settings.py:
...
import djcelery
djcelery.setup_loader()
BROKER_URL = 'django://'
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ENABLE_UTC = True
...
答案 2 :(得分:0)
以防万一有人使用Celery beat并得到相同的错误消息。在我的应用中,我使用
command=/opt/python/run/venv/bin/celery beat -A appname --loglevel=INFO --workdir=/tmp -S django --pidfile /tmp/celerybeat.pid
,并收到此错误消息。由于我复制了用于使用超级用户来监控Celery beat的大部分代码(为此您需要特殊的配置),因此我没有意识到“ -S django”假定使用了以前未安装的django_celery_beat软件包。我安装它是因为它无论如何对于生产使用都具有优势,并且错误消失了。