Django-celery-beat: CELERY_BEAT_SCHEDULE overrides schdule in database

Created on 5 Jul 2018  路  2Comments  路  Source: celery/django-celery-beat

In settings I have:
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' CELERY_BEAT_SCHEDULE = { 'test': { 'task': 'apps.testapp.tasks.test', 'schedule': crontab(minute='*/10', hour='*/1'), }, }
Then I go to admin/periodic tasks and change crontab on test tesk to crontab(minute='/2', hour='/1') and all is good (crontab of task was changed and working as expected)
But if I will restart celery, schedule of test tasl will be returned to crontab(minute='/10', hour='/1'), (read from settings). So how I can configure celery to not override exiting tasks in database from settings and only add new tasks if that exists in settings.py?

Most helpful comment

For anyone interested for a fix regarding this, I have created a custom database scheduler that doesn't do updates on restart.

from django_celery_beat.models import PeriodicTask
from django_celery_beat.schedulers import DatabaseScheduler, ModelEntry


class CustomModelEntry(ModelEntry):

    @classmethod
    def from_entry(cls, name, app=None, **entry):
        obj, _ = PeriodicTask._default_manager.get_or_create(
            name=name, defaults=cls._unpack_fields(**entry),
        )
        return cls(obj, app=app)


class CustomDatabaseScheduler(DatabaseScheduler):
    Entry = CustomModelEntry

Use this option for celery beat command --scheduler myproject.schedulers:CustomDatabaseScheduler , replace myproject.schedulers to the path where you saved the code.

All 2 comments

I encountered the same issue with the configured periodic tasks in django's settings.py. After some investigation I saw that the scheduler does an update_or_create for each entry defined in CELERY_BEAT_SCHEDULE, it will be nice to have a boolean setting that specifies you don't want to override existing entries, so the scheduler will do a get_or_create (using task name).

For anyone interested for a fix regarding this, I have created a custom database scheduler that doesn't do updates on restart.

from django_celery_beat.models import PeriodicTask
from django_celery_beat.schedulers import DatabaseScheduler, ModelEntry


class CustomModelEntry(ModelEntry):

    @classmethod
    def from_entry(cls, name, app=None, **entry):
        obj, _ = PeriodicTask._default_manager.get_or_create(
            name=name, defaults=cls._unpack_fields(**entry),
        )
        return cls(obj, app=app)


class CustomDatabaseScheduler(DatabaseScheduler):
    Entry = CustomModelEntry

Use this option for celery beat command --scheduler myproject.schedulers:CustomDatabaseScheduler , replace myproject.schedulers to the path where you saved the code.

Was this page helpful?
0 / 5 - 0 ratings