Django – 设置计划任务?
我一直在使用Django开发一个web应用程序,我很好奇是否有办法安排一个作业定期运行。
基本上我只是想通过数据库运行一些自动,定期的计算/更新,但我似乎无法找到任何文件这样做。
有谁知道如何设置?
澄清:我知道我可以设置一个cron
工作来做到这一点,但我很好奇,如果Django中有一些功能提供这个功能。 我希望人们能够自己部署这个应用程序,而不必做很多配置(最好是零)。
我曾经考虑通过简单地检查自上一次请求发送到站点以来是否应该运行一个工作来触发这些“追溯”操作,但是我希望有一些更清洁的东西。
我采用的一个解决方案是这样做的:
1)创建一个自定义的管理命令 ,例如
python manage.py my_cool_command
2)使用cron
(在Linux上)或(在Windows上)在需要的时间运行我的命令。
这是一个简单的解决方案,不需要安装沉重的AMQP堆栈。 然而,在其他答案中提到的使用像芹菜这样的东西有很多好处。 特别是在Celery中,不用将应用程序逻辑分散到crontab文件中就可以了。 但是,cron解决方案对于中小型应用程序来说工作得非常好,并且不需要太多的外部依赖。
编辑:
在Windows的更高版本中,对于Windows 8,Server 2012及更高版本,不推荐使用at
命令。 您可以使用schtasks.exe
相同的用途。
Celery是一个基于AMQP(RabbitMQ)的分布式任务队列。 它也以类似cron的方式处理定期任务(请参阅定期任务 )。 根据你的应用程序,这可能是值得的一个甘德。
芹菜是很容易与Django的( 文档 )设置,定期任务将实际上跳过错过任务的情况下停机。 芹菜也有内置的重试机制,以防任务失败。
我们已经开源了我认为是一个结构化的应用程序。 Brian的解决方案也是如此。 会爱任何/所有的反馈!
https://github.com/tivix/django-cron
它带有一个管理命令:
./manage.py runcrons
这样做的工作。 每个cron被建模为一个类(所以它的所有OO),每个cron以不同的频率运行,我们确保相同的cron类型不会并行运行(如果cron本身需要比它们的频率更长的时间运行)!
谢谢!
如果你使用的是标准的POSIX操作系统,你可以使用cron 。
如果您使用的是Windows,则可以使用。
写一个Django管理命令
-
找出他们在哪个平台上。
-
要么为您的用户执行适当的“AT”命令,要么为您的用户更新crontab。
有趣的新插件Django应用程序: Django计时
您只需添加一个充当定时器的cron条目,并且在运行的脚本中有一个非常好的Django管理界面。
看看Django Poor Man's Cron,它是一个Django应用程序,它利用垃圾邮件,搜索引擎索引机器人等以大致有规律的间隔运行计划任务
请参阅: http : //code.google.com/p/django-poormanscron/
Brian Neal的建议是通过cron运行管理命令,但是如果你正在寻找一些更强大的功能(但不像Celery那样精致),我会考虑像Kronos这样的库:
# app/cron.py import kronos @kronos.register('0 * * * *') def task(): pass
RabbitMQ和Celery比Cron有更多的功能和任务处理能力。 如果任务失败不是问题,并且您认为在下一次调用中您将处理中断的任务,那么Cron就足够了。
芹菜和AMQP可以让你处理中断的任务,并且由另一个工作人员再次执行(芹菜工作人员监听下一个要处理的任务),直到达到任务的max_retries
属性。 您甚至可以调用失败时的任务,例如记录失败,或者在达到max_retries
向管理员发送电子邮件。
当需要扩展您的应用程序时,您可以分发Celery和AMQP服务器。
我个人使用cron,但django-extensions的Jobs Scheduling部分看起来很有趣。
将以下内容放在cron.py文件的顶部:
#!/usr/bin/python import os, sys sys.path.append('/path/to/') # the parent directory of the project sys.path.append('/path/to/project') # these lines only needed if not on path os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings' # imports and code below
我只是想到这个相当简单的解决方案:
- 像使用其他视图一样定义一个视图函数do_work(req,param) ,使用URL映射,返回一个HttpResponse等等。
- 使用运行curl http:// localhost / your / mapped / url?param = value的计时首选项(或使用AT或Windows中的计划任务)设置一个cron作业。
您可以添加参数,只需将参数添加到URL即可。
告诉我你们的想法。
[更新]我现在使用django-extensions而不是curl的runjob命令。
我的cron看起来像这样:
@hourly python /path/to/project/manage.py runjobs hourly
…每天,每月等“。 你也可以设置它来运行一个特定的工作。
我觉得它更可管理,更清洁。 不需要将URL映射到视图。 只要定义你的工作类和crontab,你就定了。
虽然不是Django的一部分,但Airflow是一个较新的项目(截至2016年),对于任务管理非常有用。
Airflow是一个工作流自动化和调度系统,可用于创建和管理数据管道。 基于Web的UI为开发人员提供了一系列用于管理和查看这些管道的选项。
Airflow是用Python编写的,使用Flask构建。
Airflow由Maxime Beauchemin在Airbnb创建,2015年春季开源。它于2016年冬季加入了Apache软件基金会的孵化计划。以下是Git项目页面以及一些额外的背景信息 。
在部分代码之后,我可以写任何东西就像我的views.py 🙂
####################################### import os,sys sys.path.append('/home/administrator/development/store') os.environ['DJANGO_SETTINGS_MODULE']='store.settings' from django.core.management impor setup_environ from store import settings setup_environ(settings) #######################################
从http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/
我今天有类似的问题。
我不想让服务器处理cron(而且大多数的库最终只是cron助手)。
所以我创建了一个调度模块,并将其附加到init 。
这不是最好的方法,但它可以帮助我把所有的代码放在一个地方,执行与主应用程序有关。
是的,上面的方法是如此之大。 我尝试了其中的一些。 最后,我找到了这样一个方法:
from threading import Timer def sync(): do something... sync_timer = Timer(self.interval, sync, ()) sync_timer.start()
就像递归一样。
好的,我希望这个方法能够满足你的要求。 🙂
我用芹菜来创造我的周期性任务。 首先,您需要按如下方式安装它:
pip install django-celery
不要忘记在你的设置中注册django-celery
,然后你可以做这样的事情:
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
我不确定这对任何人都有用,因为我不得不提供系统的其他用户来安排工作,而不让他们访问实际的服务器(Windows)任务计划,我创建了这个可重用的应用程序。
请注意,用户可以访问服务器上的一个共享文件夹,他们可以创建所需的命令/任务/ .bat文件。 这个任务,然后可以安排使用这个应用程序。
应用程序名称是Django_Windows_Scheduler
截图:
我刚才有完全相同的要求,最后用APScheduler ( 用户指南 )
它使调度工作变得非常简单,并且保持它独立于某些代码的基于请求的执行。 以下是我在代码中使用的一个简单示例。
from apscheduler.schedulers.background import BackgroundScheduler scheduler = BackgroundScheduler() job = None def tick(): print('One tick!')\ def start_job(): global job job = scheduler.add_job(tick, 'interval', seconds=3600) try: scheduler.start() except: pass
希望这有助于某人!
与芹菜相比,更现代的解决方案是Django Q: https : //django-q.readthedocs.io/en/latest/index.html
它有很好的文档,很容易理解。 缺少Windows支持,因为Windows不支持进程分叉。 但是,如果使用Windows for Linux子系统创建开发环境,则工作正常。