使用 Celery 的单个 Django 模型的每个对象的不同 crontab

Posted

技术标签:

【中文标题】使用 Celery 的单个 Django 模型的每个对象的不同 crontab【英文标题】:Different crontab for each objects of single Django model using Celery 【发布时间】:2019-09-21 08:48:05 【问题描述】:

我能够创建 celery_beat_schedule 并且它可以工作。耶!

但我想知道是否有任何方法可以为同一 Django 模型的不同对象创建 cronjob。

Settings.py

CELERY_BEAT_SCHEDULE = 
    'ok': 
        'task' : 'bill.tasks.ok',
        'schedule' : crontab(minute=27, hour=0),
        # 'args' : (*args)
    

bill/tasks.py

from celery import task
@task
def ok():
    bills = Bill.objects.all()
    for bill in bills:
        perform_something(bill)

我想更改每个对象的 crontab 时间。我该怎么做?

假设我在模型对象中有一个小时和分钟的值

感谢您的宝贵时间 :)

好吧,我无法找到如何为每个任务实例运行不同的 crontab。但是还有另一种运行方式。只需每小时运行一次 crontab,每次检查您的查询是否与 tasks.py 中的当前时间匹配。

【问题讨论】:

【参考方案1】:

您可以在参数中指定值,然后在过滤查询集时使用它们。

Settings.py

CELERY_BEAT_SCHEDULE = 
    'ok_27_0': 
        'task' : 'bill.tasks.ok',
        'schedule' : crontab(minute=27, hour=0),
        'args' : (27, 0)
    ,
    'ok_5_any': 
        'task' : 'bill.tasks.ok',
        'schedule' : crontab(minute=5),
        'args' : (5, None)
    

bill/tasks.py

from celery import task
@task
def ok(minute=None, hour=None):
    bills = Bill.objects.all()

    if minute is not None:
        bills = bills.filter(minute=minute)
    if hour is not None:
        bills = bills.filter(hour=hour)

    for bill in bills:
        perform_something(bill)

编辑:

您可能还想尝试绑定任务并查看是否可以在任务实例或其请求中找到任务的计划。这样您就不必在设置中重复自己。但是,我不知道这是否可能。

@task(bind=True)
def ok(self):
    self.request

【讨论】:

感谢@schillingt 成功了。但是在这里,如果参数值很多(分钟和小时的组合),我们会硬编码不适合的参数。我正在寻找绑定任务。我会发布相同的。

以上是关于使用 Celery 的单个 Django 模型的每个对象的不同 crontab的主要内容,如果未能解决你的问题,请参考以下文章

使用 django-celery 时如何创建单个类对象?

如何在 celery 任务中强制 django-orm 中的单个保存的 db 提交

如何在任务中获取芹菜结果模型(使用 django-celery-results)

如何将自定义模型添加到 django celery

Django 模型和 Celery 周期性任务

为啥当我尝试在 celery 任务中使用模型时,django 会引发“应用程序尚未加载”错误?