从celery_beat中删除项目不会从数据库计划中删除它们



我在Django应用中使用django-celery-beat(这将附表存储在数据库中,而不是本地文件(。我已经通过celery_beat配置了我的时间表,该芹菜是通过app.config_from_object(...)

初始化的。

我最近重命名/删除了一些任务,然后重新启动了该应用程序。出现了新任务,但是从celery_beat字典中删除的任务并未从数据库中删除。

这个预期的工作流程是否需要手动从数据库中删除任务?是否有解决方法可以自动调和Django启动的时间表?

我在celery/__init__.py

中尝试了PeriodicTask.objects.all().delete()
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()中的查询/db连接。

查看 django-celery-beat的实际工作方式来安装时间表,我认为我也许可以将其连接到该过程中。

当django启动时,它不会发生 - 当 beat 启动时,它会发生。它将setup_schedule()与Beat命令行中通过的类调用。

因此,我们可以用

覆盖调度程序
--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管理员或编程添加任务,也将删除它们。

相关内容

  • 没有找到相关文章

最新更新