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.

431
demandé sur WhiteKnight 2009-02-21 22:39:59

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.

312
répondu Brian Neal 2016-01-27 08:24:50

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.

124
répondu dln 2017-02-06 00:58:01

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!

43
répondu chachra 2012-01-30 21:47:06

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

  1. Trouvez sur quelle plate-forme ils sont.

  2. Exécutez la commande " AT " appropriée pour vos utilisateurs, ou mettez à jour la crontab pour vos utilisateurs.

32
répondu S.Lott 2016-09-11 00:04:44

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.

22
répondu Van Gale 2017-10-03 13:31:40

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

Voir: http://code.google.com/p/django-poormanscron/

14
répondu user41767 2009-02-21 20:29:47

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
9
répondu Johannes Gorset 2011-12-26 00:23:52

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.

9
répondu Ravi Kumar 2015-04-05 23:17:57

Personnellement, j'utilise cron, mais le Emplois de Planification de parties de django-extensions semble intéressant.

8
répondu Van Gale 2013-09-05 15:08:39

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
6
répondu Matt McCormick 2010-01-07 23:26:10

Je viens de penser à cette solution plutôt simple:

  1. 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.
  2. 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.

6
répondu Michael 2012-01-25 21:15:07

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.

6
répondu Alexander 2016-07-19 20:49:43

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!

6
répondu PhoenixDev 2017-06-22 14:04:20

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/

4
répondu xiaohei 2011-05-17 03:09:13

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.

2
répondu Fabricio Buzeto 2011-09-02 18:41:33

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. :)

2
répondu Ni Xiaoni 2014-03-26 01:04:36

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
1
répondu David Felipe Camargo Polo 2015-08-31 22:23:38

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

Capture D'écran: entrez la description de l'image ici

1
répondu just10minutes 2017-01-11 19:34:28

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.

1
répondu devdrc 2017-11-11 16:38:15

, 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,
},
}
1
répondu saran3h 2018-08-04 05:50:24

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

0
répondu Sriram 2018-05-21 23:53:52