本文介绍了无法在Django中运行Celery任务-我要么收到"AppRegistryNotReady:应用尚未加载",或"RuntimeError:populate()未重入"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to setup a task with Celery in Django to run every day at 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:应用尚未加载..

The problem is that in this function, I have Rating = apps.get_model(app_label='App', model_name='Rating'), and If I don't call django.setup() then I get django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet..

但是,如果我调用 django.setup(),则任务运行正常,但由于得到 RuntimeError,我无法执行 manage.py runserver :populate()不可重入.

However, If I call django.setup(), the tasks are running fine but I can't do manage.py runserver as I get RuntimeError: populate() isn't reentrant.

有解决方案吗?

推荐答案

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

I'm not sure exactly how to reproduce the environment you're in, so here are some observations from my environment, I hope they help

我拥有 Celery()对象的唯一位置是在一个独立文件中,该文件保存在"manage.py startproject"文件中.生成的程序包

The only place I have a Celery() object is in a standalone file, kept within the "manage.py startproject" generated package,

我认为与大多数django用户相比,我布置django应用的方式很不寻常,因此请对其进行描述:

I think the way I layout a django app is unusual compared to most django users, so to describe it:

# .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文件夹'env'是所生成的exampleproject包的同级

and I start the celery jobs like as follows, where my python virtual env folder 'env' is a sibling of the generated exampleproject package

(
        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'


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

With these parts, I haven't noticed any issues loading the entry points

这篇关于无法在Django中运行Celery任务-我要么收到"AppRegistryNotReady:应用尚未加载",或"RuntimeError:populate()未重入"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 20:57