Django-Mettre En Place Une Tâche Planifiée?
J'ai travaillé sur une application web utilisant Django, et je suis curieux de savoir s'il existe un moyen de planifier un travail à exécuter périodiquement.
Fondamentalement, je veux juste parcourir la base de données et faire des calculs/mises à jour sur une base automatique et régulière, mais je n'arrive pas à trouver de documentation à ce sujet.
Est ce que quelqu'un sait comment configurer cela?
Pour clarifier: je sais que je peux configurer un travail cron
pour le faire, mais je suis curieux de savoir s'il y a une fonctionnalité dans Django qui fournit cette fonctionnalité. Je voudrais que les gens puissent déployer cette application eux-mêmes sans avoir à faire beaucoup de config (de préférence zéro).
J'ai envisagé de déclencher ces actions "rétroactivement" en vérifiant simplement si un travail aurait dû être exécuté depuis la dernière fois qu'une requête a été envoyée sur le site, mais j'espère quelque chose d'un peu plus propre.
21 réponses
Une solution que j'ai employée est de faire ceci:
1) créez une commande de gestion personnalisée , par exemple
python manage.py my_cool_command
2) Utilisez cron
(sous Linux) ou at
(sous Windows) pour exécuter ma commande aux heures requises.
C'est une solution simple qui ne nécessite pas l'installation d'une pile AMQP lourde. Cependant, il y a de beaux avantages à utiliser quelque chose comme le céleri, mentionné dans les autres réponses. En particulier, avec le céleri, il est agréable de ne pas avoir à répandre votre logique d'application dans les fichiers crontab. Cependant, la solution cron fonctionne très bien pour une application de petite à moyenne taille et où vous ne voulez pas beaucoup de dépendances externes.
Modifier:
Dans la version ultérieure de windows, la commande at
est obsolète Pour Windows 8, Server 2012 et versions ultérieures. Vous pouvez utiliser schtasks.exe
pour le même usage.
Celery {[2] } est une file d'attente de tâches distribuée, construite sur AMQP (RabbitMQ). Il gère également les tâches périodiques de manière similaire à cron (voir tâches périodiques ). Selon votre application, cela pourrait valoir la peine d'un coup d'œil.
Celery est assez facile à configurer avec django (docs), et les tâches périodiques sauteront les tâches manquées en cas d'arrêt. Céleri a également intégré dans les mécanismes de réessayer, au cas où une tâche échoue.
Nous avons ouvert ce que je pense être une application structurée. Cette solution de Brian ci-dessus fait aussi allusion. Aimerait tout / tous les commentaires!
Https://github.com/tivix/django-cron
Il est livré avec une commande de gestion:
./manage.py runcrons
Ça fait le boulot. Chaque cron est modélisé en tant que classe (donc c'est tout OO) et chaque cron s'exécute à une fréquence différente et nous nous assurons que le même type de cron ne fonctionne pas en parallèle (au cas où les crons eux-mêmes prennent plus de temps à courir que leur fréquence!)
Merci!
Si vous utilisez un système D'exploitation POSIX standard, vous utilisez cron .
Si vous utilisez Windows, vous utilisez à.
Ecrire une commande de gestion Django dans
Trouvez sur quelle plate-forme ils sont.
Exécutez la commande " AT " appropriée pour vos utilisateurs, ou mettez à jour la crontab pour vos utilisateurs.
Nouvelle application Django enfichable intéressante: django-chronograph
Il suffit d'ajouter une entrée cron qui agit comme une minuterie, et vous avez une très belle interface D'administration Django dans les scripts à exécuter.
Regardez Django Poor Man's Cron qui est une application Django qui utilise des robots spammeurs, des robots d'indexation de moteurs de recherche et autres pour exécuter des tâches planifiées à intervalles réguliers
La suggestion de Brian Neal d'exécuter des commandes de gestion via cron fonctionne bien, mais si vous cherchez quelque chose d'un peu plus robuste (mais pas aussi élaboré que Celery), je regarderais dans une bibliothèque comme Kronos :
# app/cron.py
import kronos
@kronos.register('0 * * * *')
def task():
pass
RabbitMQ et Celery ont plus de fonctionnalités et de capacités de gestion des tâches que Cron. Si l'échec de la tâche n'est pas un problème et que vous pensez Gérer les tâches brisées lors du prochain appel, Cron est suffisant.
Celery & AMQP vous permettra de gérer la tâche brisée, et elle sera exécutée à nouveau par un autre travailleur (les travailleurs de céleri écoutent la tâche suivante), jusqu'à ce que l'attribut max_retries
de la tâche soit atteint. Vous pouvez même appeler des tâches en cas d'échec, comme la journalisation de l'échec ou envoyer un e-mail à l'administrateur une fois que le max_retries
a été atteint.
Et vous pouvez distribuer des serveurs Celery et AMQP lorsque vous avez besoin de mettre à l'échelle votre application.
Personnellement, j'utilise cron, mais le Emplois de Planification de parties de django-extensions semble intéressant.
Mettez ce qui suit en haut de votre cron.py fichier:
#!/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
Je viens de penser à cette solution plutôt simple:
- Définissez une fonction de vue do_work (req, param) comme vous le feriez avec n'importe quelle autre vue, avec le mappage D'URL, renvoyez une réponse HttpResponse et ainsi de suite.
- Configurez un travail cron avec vos préférences de synchronisation (ou en utilisant des tâches AT ou planifiées dans Windows) qui exécute curl http://localhost/your/mapped/url?param=valeur.
Vous pouvez ajouter des paramètres mais simplement ajouter des paramètres à L'URL.
Dites-moi ce que vous en pensez.
[Update] j'utilise maintenant la commande runjob de django-extensions au lieu de curl.
Mon cron ressemble à ceci:
@hourly python /path/to/project/manage.py runjobs hourly
... et ainsi de suite pour tous les jours, mensuel, etc'. Vous pouvez également le configurer pour exécuter une tâche spécifique.
Je le trouve plus maniable et plus propre. Ne nécessite pas le mappage D'une URL à une vue. Il suffit de définir votre classe de travail et crontab et vous êtes prêt.
Bien que ne faisant pas partie de Django, Airflow est un projet Plus Récent (à partir de 2016) qui est utile pour la gestion des tâches.
Airflow est un système d'automatisation et de planification de flux de travail qui peut être utilisé pour créer et gérer des pipelines de données. Une interface utilisateur basée sur le web fournit au développeur une gamme d'options pour la gestion et l'affichage de ces pipelines.
Airflow est écrit en Python et est construit en utilisant Flask.
Airflow a été créé par Maxime Beauchemin chez Airbnb et open source au printemps 2015. Il a rejoint le programme d'incubation de la Fondation Apache Software à l'hiver 2016. Voici la page du projet git et quelques ajouts Informations générales.
J'avais exactement la même exigence il y a un moment, et j'ai fini par la résoudre en utilisant APScheduler (Guide de L'utilisateur )
Cela rend la planification des tâches super simple et la maintient indépendante de l'exécution basée sur les requêtes de certains codes. Voici un exemple simple que j'ai utilisé dans mon code.
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
J'espère que cela aide quelqu'un!
Après la partie de code, je peux écrire n'importe quoi comme mon 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)
#######################################
Depuis http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/
J'ai eu quelque chose de similaire avec votre problème aujourd'hui.
Je ne voulais pas le faire gérer par le serveur trhough cron (et la plupart des libs n'étaient que des aides cron à la fin).
J'ai Donc créé un module de planification et attaché à l' init .
Ce n'est pas la meilleure approche, mais cela m'aide à avoir tout le code en un seul endroit et avec son exécution liée à l'application principale.
Oui, la méthode ci-dessus est si grande. Et j'ai essayé quelques-uns d'entre eux. Enfin, j'ai trouvé une méthode comme ceci:
from threading import Timer
def sync():
do something...
sync_timer = Timer(self.interval, sync, ())
sync_timer.start()
Tout comme récursif .
Ok, j'espère que cette méthode peut répondre à vos besoins. :)
J'utilise le céleri pour créer mes tâches périodiques. Vous devez d'abord l'installer comme suit:
pip install django-celery
N'oubliez pas d'enregistrer django-celery
dans vos paramètres et vous pouvez ensuite faire quelque chose comme ceci:
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
Je ne suis pas sûr que cela sera utile pour quiconque, puisque j'ai dû fournir à d'autres utilisateurs du système pour planifier les travaux, sans leur donner accès au Planificateur de tâches du serveur réel(windows), j'ai créé cette application réutilisable.
Veuillez noter que les utilisateurs ont accès à un dossier partagé sur le serveur où ils peuvent créer la commande/tâche / requise.le fichier bat. Cette tâche peut alors être planifiée en utilisant cette application.
Le nom de L'application est Django_Windows_Scheduler
Une solution plus moderne (par rapport au céleri) est Django Q: https://django-q.readthedocs.io/en/latest/index.html
Il a une grande documentation et est facile à grok. Le support de Windows fait défaut, car Windows ne prend pas en charge la bifurcation des processus. Mais cela fonctionne bien si vous créez votre environnement de développement en utilisant le sous-système Windows Pour Linux.
, Vous devriez certainement vérifier django-q! Il ne nécessite aucune configuration supplémentaire et a très probablement tout le nécessaire pour gérer les problèmes de production sur les projets commerciaux.
Il est activement développé et s'intègre très bien avec django, django ORM, mongo, redis. Voici ma configuration:
# django-q
# -------------------------------------------------------------------------
# See: http://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
# Match recommended settings from docs.
'name': 'DjangoORM',
'workers': 4,
'queue_limit': 50,
'bulk': 10,
'orm': 'default',
# Custom Settings
# ---------------
# Limit the amount of successful tasks saved to Django.
'save_limit': 10000,
# See https://github.com/Koed00/django-q/issues/110.
'catch_up': False,
# Number of seconds a worker can spend on a task before it's terminated.
'timeout': 60 * 5,
# Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
# longer than `timeout`, otherwise the same task will be processed multiple times.
'retry': 60 * 6,
# Whether to force all async() calls to be run with sync=True (making them synchronous).
'sync': False,
# Redirect worker exceptions directly to Sentry error reporter.
'error_reporter': {
'sentry': RAVEN_CONFIG,
},
}
Si vous voulez quelque chose de plus fiable que Celery , Essayez TaskHawkqui est construit sur AWS SQS/SNS.
Se référer: http://taskhawk.readthedocs.io