我在django应用程序中使用django-celery-beat
(这将日程表存储在数据库中,而不是本地文件中)。我已通过celery_beat
配置了计划,以通过app.config_from_object(...)
我最近重命名/删除了一些任务,然后重新启动了该应用程序。出现了新任务,但是从celery_beat
词典中删除的任务并未从数据库中删除。
这是预期的工作流程-是否需要从数据库中手动删除任务?有没有变通办法可以在Django启动时自动调整计划?
我在PeriodicTask.objects.all().delete()
中尝试过celery/__init__.py
def _clean_schedule():
from django.db import transaction
from django_celery_beat.models import PeriodicTask
from django_celery_beat.models import PeriodicTasks
with transaction.atomic():
PeriodicTask.objects.\
exclude(task__startswith='celery.').\
exclude(name__in=settings.CELERY_CONFIG.celery_beat.keys()).\
delete()
PeriodicTasks.update_changed()
_clean_schedule()
但这是不允许的,因为Django尚未正确启动:
django.core.exceptions.AppRegistryNotReady:应用尚未加载。
您也不能使用Django的AppConfig.ready()
,因为不支持在ready()
中进行查询/数据库连接。
答案 0 :(得分:1)
看看django-celery-beat
实际如何安装时间表,我想我也许可以参与该过程。
在Django启动时不会发生-在 beat 启动时会发生。它会向Beat命令行上传递的类调用setup_schedule()
。
因此,我们可以使用
覆盖计划程序。--scheduler=myproject.lib.scheduler:DatabaseSchedulerWithCleanup
进行清理:
import logging
from django_celery_beat.models import PeriodicTask
from django_celery_beat.models import PeriodicTasks
from django_celery_beat.schedulers import DatabaseScheduler
from django.db import transaction
class DatabaseSchedulerWithCleanup(DatabaseScheduler):
def setup_schedule(self):
schedule = self.app.conf.beat_schedule
with transaction.atomic():
num, info = PeriodicTask.objects.\
exclude(task__startswith='celery.').\
exclude(name__in=schedule.keys()).\
delete()
logging.info("Removed %d obsolete periodic tasks.", num)
if num > 0:
PeriodicTasks.update_changed()
super(DatabaseSchedulerWithCleanup, self).setup_schedule()
请注意,仅当您使用beat_schedule
专门管理任务时,才需要这样做。如果您通过Django管理员或以编程方式添加任务,这些任务也会被删除。