【问题标题】:Unable to run celery task that depends on Django code无法运行依赖于 Django 代码的 celery 任务
【发布时间】:2020-02-29 12:37:03
【问题描述】:

在尝试运行依赖于 django 代码的 celery 任务时,我似乎遇到了一些 catch 22 场景。

芹菜代码

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings
from celery import shared_task
from celery import task
from letters.send_write_letter_reminders import send_write_letter_reminders

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app_name.settings')

app = Celery('app_name')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

app.conf.timezone = 'Europe/London'
# Load task modules from all registered Django app configs.
app.autodiscover_tasks(settings.INSTALLED_APPS)

@app.task(bind=True, name='send_letter_reminders')
def send_letter_reminders(slug=None):
    send_write_letter_reminders(slug=slug)

我遇到的问题是这条线

from letters.send_write_letter_reminders import send_write_letter_reminders

有了它,我得到:

django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

应用服务器将无法运行,但没有它我会得到:

NameError: name 'send_write_letter_reminders' is not defined

显然,我缺少有关如何一起运行 Celery 和 Django 的基本知识,但我看不到它。谁能告诉我我做错了什么?

更新 我为此提出了一个 hacky 解决方法,其中涉及将导入移动到 celery 任务中。我意识到这不是最佳做法。也许它可能有助于解释发生了什么。

@app.task(bind=True, name='send_letter_reminders')
def send_letter_reminders(slug=None):
    from letters.send_write_letter_reminders import send_write_letter_reminders
    send_write_letter_reminders.send_write_letter_reminders(slug=slug)

【问题讨论】:

    标签: django celery django-celery


    【解决方案1】:

    基本上,在您执行os.environ.setdefault 行之前,您不能执行任何 django 导入或导入任何依赖 django 的内容。您不必担心从manage.py 运行的任何内容的原因是因为os.environ.setdefault 是manage.py 的第一行。本质上,只需将 django.confletter 导入移动到 os.environ.setdefault 下方,事情应该会更好。根据您使用的 django 版本,您可能还需要在设置 DJANGO_SETTINGS_MODULE 后显式调用 django.setup() 以完成 django 设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      • 2011-11-22
      • 2014-03-17
      • 2023-03-24
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      相关资源
      最近更新 更多