【问题标题】:Can't run Celery task in Django - I either get "AppRegistryNotReady: Apps aren't loaded yet" or "RuntimeError: populate() isn't reentrant"无法在 Django 中运行 Celery 任务 - 我得到“AppRegistryNotReady:应用程序尚未加载”或“RuntimeError: populate() is not reentrant”
【发布时间】:2021-06-13 07:36:09
【问题描述】:

我正在尝试在 Django 中使用 Celery 设置一个任务,使其每天在 23:00 运行。

app = Celery('App.tasks', broker='redis://localhost')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "App.settings")

django.setup() <== PROBLEM

@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    sender.add_periodic_task(
        crontab(hour=23),
        calc_average_rating.s(),
    )


@app.task
def calc_average_rating(final_content_id):

问题是,在这个函数中,我有Rating = apps.get_model(app_label='App', model_name='Rating'),如果我不调用django.setup(),我就会得到django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

但是,如果我打电话给django.setup(),任务运行良好,但我不能做manage.py runserver,因为我得到RuntimeError: populate() isn't reentrant

有什么解决办法吗?

【问题讨论】:

  • 我很想知道具体问题是什么,主要是需要为 Celery 提供 django 应用程序包名称而不是任务模块名称吗?
  • 我认为问题在于我没有启动worker,因为我认为只需要beat,但我不确定。

标签: django celery django-celery


【解决方案1】:

我不确定如何重现你所处的环境,所以这里有一些来自我的环境的观察,希望它们对你有所帮助

我唯一拥有Celery() 对象的地方是一个独立文件,保存在“manage.py startproject”生成的包中,

我认为与大多数 django 用户相比,我布局 django 应用程序的方式很不寻常,所以描述一下:

# .git/  # top folder is my vcs
# setup.py  # packaging for exampleapp
# env/  # python venv created to this service
# exampleapp/  # package generated from startapp
# exampleapp/tasks.py  # package generated from startapp
# exampleproject/  # folder generated from startproject
# exampleproject/exampleproject/  # package generated by startproject
# exampleproject/exampleproject/settings.py  # generated
# exampleproject/exampleproject/celery.py  # created based on celery docs
# exampleproject/exampleproject/celery.py
import os

from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'exampleproject.settings')

app = Celery('exampleproject')

app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

@app.task(bind=True)
def debug_task(self):
    print('Request: {self.request!r}'.format(self=self))

if __name__ == '__main__':
    app.start()

然后我按如下方式启动 celery 作业,其中我的 python 虚拟环境文件夹 'env' 是生成的 exampleproject 包的兄弟

(
        cd exampleproject
        ../env/bin/python3 -m celery -A exampleproject  worker -l INFO
        # or 
        ../env/bin/python3 -m celery -A exampleproject  beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler

)
# and for django
./env/bin/python3 exampleproject/manage.py runserver

也许你也感兴趣

# exampleapp/tasks.py
from celery import shared_task

@shared_task
def add(x, y):
    return x+y
# exampleproject/exampleproject/settings.py
# suffixed to end of generated file

INSTALLED_APPS.extend([
    'django_celery_results',
    'django_celery_beat',
])

CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60
CELERY_RESULT_BACKEND = 'django-db'
#CELERY_RESULT_BACKEND = 'django-cache'


使用这些部分,我没有注意到加载入口点有任何问题

【讨论】:

    猜你喜欢
    • 2020-08-10
    • 2018-12-26
    • 1970-01-01
    • 2017-02-02
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 2016-03-10
    相关资源
    最近更新 更多