4

我正在拼命想让 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>

这对我来说肯定是可以调用的!知道会发生什么吗?如果我遗漏了什么,我很乐意发布额外的日志、文件或澄清其他任何事情。

4

3 回答 3

2

以防万一有人使用 Celery beat 并收到相同的错误消息。在我的应用程序中,我使用

command=/opt/python/run/venv/bin/celery beat -A appname --loglevel=INFO --workdir=/tmp -S django --pidfile /tmp/celerybeat.pid

并收到此错误消息。由于我使用 supervisord 复制了大部分用于守护 Celery beat 的代码(为此您需要一个特殊的配置),我没有意识到“-S django”假定使用了我之前没有安装的 django_celery_beat 包。我安装了它,因为它无论如何都具有生产使用的优势,并且错误消失了。

于 2019-07-31T14:21:22.793 回答
1

(转换为评论的答案)

堆栈跟踪中,我认为该行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,并向上移动堆栈(updb 中的命令, d再次向下,w以显示调用堆栈)以调试出错的地方。

celery 文档也提到了这一点:

如何导入任务装饰器?

任务装饰器在您的 Celery 实例上可用,如果您不知道那是什么,请阅读 Celery 的第一步。

如果您使用 Django 或仍在使用基于“旧”模块的 celery API,那么您可以像这样导入任务装饰器:

from celery import task

@task
def add(x, y):
    return x + y

所以这应该消除关于导入任务装饰器的方式是正确的方式的任何歧义。

于 2013-08-08T10:01:40.313 回答
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

...
于 2014-06-10T09:44:18.873 回答