我一直在使用Django开发一个web应用程序,我很好奇是否有一种方法可以安排一个作业定期运行。

基本上,我只是想运行数据库,并在自动的、定期的基础上进行一些计算/更新,但我似乎找不到任何关于这样做的文档。

有人知道怎么设置吗?

澄清一下:我知道我可以设置一个cron作业来完成这个任务,但我很好奇Django中是否有一些特性提供了这个功能。我希望人们能够自己部署这个应用程序,而不需要做很多配置(最好是零配置)。

我曾经考虑过“回溯性”地触发这些操作,方法是简单地检查自上一次请求发送到站点以来作业是否应该运行,但我希望使用更简洁的方法。


当前回答

如果你想要比芹菜更可靠的东西,可以尝试构建在AWS SQS/SNS之上的TaskHawk。

参见:http://taskhawk.readthedocs.io

其他回答

我采用的一个解决方案是这样的:

1)创建一个自定义管理命令,例如:

python manage.py my_cool_command

2)使用cron(在Linux上)或at(在Windows上)在需要的时间运行我的命令。

这是一个简单的解决方案,不需要安装沉重的AMQP堆栈。然而,使用像芹菜这样的东西有很好的优点,在其他答案中提到过。特别是,使用芹菜,不需要将应用程序逻辑扩展到crontab文件中是很好的。然而,cron解决方案非常适合中小型应用程序,并且不需要大量外部依赖。

编辑:

在windows的后续版本中,at命令在windows 8、Server 2012及以上版本中已弃用。你可以使用schtasks.exe来做同样的事情。

****更新**** 这是django doc中用来编写自定义管理命令的新链接

我个人使用cron,但是django扩展的作业调度部分看起来很有趣。

我用芹菜来创建我的定期任务。首先你需要安装它,如下所示:

pip install django-celery

不要忘记在你的设置中注册django-芹菜,然后你可以这样做:

from celery import task
from celery.decorators import periodic_task
from celery.task.schedules import crontab
from celery.utils.log import get_task_logger
@periodic_task(run_every=crontab(minute="0", hour="23"))
def do_every_midnight():
 #your code

RabbitMQ和芹菜比Cron有更多的特性和任务处理能力。如果任务失败不是问题,并且您认为将在下一个调用中处理中断的任务,那么Cron就足够了。

Celery & AMQP将允许您处理中断的任务,它将由另一个worker再次执行(Celery worker侦听下一个要处理的任务),直到到达任务的max_retries属性。您甚至可以在失败时调用任务,比如记录失败,或者在到达max_retries时向管理员发送电子邮件。

当需要扩展应用程序时,可以分发芹菜和AMQP服务器。

另一种选择是使用火箭技术:

from rocketry import Rocketry
from rocketry.conds import daily, after_success

app = Rocketry()

@app.task(daily.at("10:00"))
def do_daily():
    ...

@app.task(after_success(do_daily))
def do_after_another():
    ...

if __name__ == "__main__":
    app.run()

它还支持自定义条件:

from pathlib import Path

@app.cond()
def file_exists(file):
    return Path(file).exists()

@app.task(daily & file_exists("myfile.csv"))
def do_custom():
    ...

它也支持Cron:

from rocketry.conds import cron

@app.task(cron('*/2 12-18 * Oct Fri'))
def do_cron():
    ...

它可以很好地与FastAPI集成,我认为它也可以与Django集成,Rocketry本质上只是一个复杂的循环,可以生成异步任务,线程和进程。

声明:我是作者。