如何在 Django 中每天一次在准确的时间执行命令?

Posted

技术标签:

【中文标题】如何在 Django 中每天一次在准确的时间执行命令?【英文标题】:How to execute a command at exact time once a day in Django? 【发布时间】:2012-08-09 02:21:59 【问题描述】:

我正在开发一个基于 Django 网络的项目,我需要在其中构建一个按以下顺序工作的应用程序:

1) 用户打开一个页面,他需要在其中输入commandtime

2) Django 应用程序将在每天的给定时间执行该命令,直到用户关闭调度程序(默认为 True)

我面临的问题是:

1) 我应该如何一次但每天执行命令。为了节省命令和时间,我在 models.py 中创建了一个以下模型

class commands(models.Model):
    username = models.ForeignKey(User)
    command = models.CharField(max_length=30)
    execution_time = models.DateField()

我有相同的时间,但我没有在每天的给定时间以正确的方式执行它

是否可以使用pytz 库?

为了执行我使用paramiko库的命令

PS:我不想使用任何外部库

【问题讨论】:

@Maulwurfn 我认为 cron 是一个库? cron 在每个 unix 系统上安装了三个十年 我对windows服务器了解不多? 你提到过 Windows Server 吗? 必须有一个很好的理由不使用 cron 或类似的(在卷绕机上)。不是你想急于重新发明它的***。 【参考方案1】:

虽然您可以让您的 django 应用程序在系统上添加和删除 cron 作业,但另一种更 django-ish 的方法是使用 Celery。它是一个可以运行同步和异步任务的任务队列系统。

Celery 的一个特殊功能是计划任务:http://packages.python.org/celery/userguide/periodic-tasks.html

from datetime import timedelta

CELERYBEAT_SCHEDULE = 
    "runs-every-30-seconds": 
        "task": "tasks.add",
        "schedule": timedelta(seconds=30),
        "args": (16, 16)
    ,

他们还有一个更精细的周期任务版本,可以复制 crontab 的调度:

from celery.schedules import crontab

CELERYBEAT_SCHEDULE = 
    # Executes every Monday morning at 7:30 A.M
    'every-monday-morning': 
        'task': 'tasks.add',
        'schedule': crontab(hour=7, minute=30, day_of_week=1),
        'args': (16, 16),
    ,

Celery 本身是独立的,但有 django-celery 特定版本

此解决方案的好处是您无需编辑和维护系统级 cron 选项卡。这是一个高度集成到 django 中的解决方案。

另外一个巨大胜过使用 cron 是 Celery 可以随您的系统扩展。如果您使用的是基本系统 crontab,那么任务将位于托管应用程序的服务器上。但是,如果您需要扩展您的网站并在 5 个 Web 应用程序节点上运行它怎么办?您需要集中该 crontab。如果你使用 Celery,你有一个large number of options 来了解如何传输和存储任务。它本质上是分布式的,并且可以同步到您的所有应用程序服务器。它是便携式的。

【讨论】:

我应该如何添加任务。例如,要执行一项任务,我必须调用一个函数,即 *** sample_test(user, commands) *** 。我应该如何添加上面的代码? 关于更多问题,正如您定义的 *** day_of_week** 。我应该在周一和周三或一周的所有日子里做些什么改变来执行它?只是要求一个例子,因为我浏览了给定的模板但没有找到这个:) 我认为此链接可能对dynamically adding periodic tasks 有所帮助,但在您的情况下,您将希望使用CrontabSchedule 而不是IntervalSchedule 对于另一个问题,您可以指定day_of_week 作为列表来说明日期。如果根本不设置此属性,则为一周中的每一天:(Mon/Wed)crontab(hour=7, minute=30, day_of_week=[1,3]),或每天 7:30:crontab(hour=7, minute=30)【参考方案2】:

在我看来,正确的做法是写一个Django custom command 并通过cron 执行它。但是您似乎很幸运,因为其他人也有类似的需求并编写了自定义 django 应用程序。以django-cron 为例。

【讨论】:

【参考方案3】:

您的问题的解决方案是标准的cron 应用程序(*nix 系统上的任务规划器)。您可以使用 cron 安排脚本(通过将其添加到 crontab)。

如果您的脚本必须在您的 Django 应用程序环境中执行,可以使用setup_environment 函数告诉他这样做。你可以阅读更多关于 Django 应用程序的独立脚本here。

【讨论】:

以上是关于如何在 Django 中每天一次在准确的时间执行命令?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 应用程序中每 1/2 秒获取步行距离(以米为单位)和方向?

如何在rails上一次在多个不是主从关系的分片上执行rails db:迁移?

如何在 Django Admin 中为作为方法//属性的字段重命名列标签?

如何一次在本地通知中将日期数组设置为fireDate

如何测量 C# 中每一行的执行时间

如何在 Python 中每 60 秒异步执行一次函数?