it-swarm.com.ru

Django - настроить запланированное задание?

Я работал над веб-приложением с использованием Django, и мне любопытно, есть ли способ запланировать периодическое выполнение задания. 

По сути, я просто хочу пробежаться по базе данных и делать некоторые расчеты/обновления автоматически, на регулярной основе, но я не могу найти какую-либо документацию по этому вопросу.

Кто-нибудь знает, как это настроить?

Для пояснения: я знаю, что могу создать для этого задание cron, но мне любопытно, есть ли в Django какая-то функция, обеспечивающая эту функцию. Я бы хотел, чтобы люди могли сами развернуть это приложение, не выполняя много настроек (желательно нулевых).

Я подумал о том, чтобы инициировать эти действия «задним числом», просто проверив, нужно ли было запускать задание с момента последней отправки запроса на сайт, но я надеюсь на что-то более чистое.

450
TM.

Одно решение, которое я использовал, состоит в том, чтобы сделать это:

1) Создайте пользовательскую команду управления , например. 

python manage.py my_cool_command

2) Используйте cron (в Linux) или at (в Windows), чтобы запустить мою команду в нужное время.

Это простое решение, которое не требует установки тяжелого стека AMQP. Однако есть хорошие преимущества использования чего-то вроде сельдерея, упомянутые в других ответах. В частности, с Celery хорошо, что нет необходимости распространять логику вашего приложения в файлы crontab. Однако решение cron довольно хорошо работает для приложений малого и среднего размера, где вам не нужно много внешних зависимостей.

Правка:

В более поздней версии Windows команда at устарела для Windows 8, Server 2012 и выше. Вы можете использовать schtasks.exe для того же самого использования.

325
Brian Neal

Celery - это распределенная очередь задач, построенная на AMQP (RabbitMQ). Он также обрабатывает периодические задачи в стиле крона (см. периодические задачи ). В зависимости от вашего приложения, это может стоить того.

Celery довольно легко настроить с помощью Django ( docs ), и периодические задачи фактически пропускают пропущенные задачи в случае простоя. У сельдерея также есть встроенные механизмы повтора, в случае неудачи.

128
dln

Мы с открытым исходным кодом, что я думаю, является структурированным приложением. это решение Брайана также намекает. Буду рад любой/все отзывы!

https://github.com/tivix/Django-cron

Он поставляется с одной командой управления:

./manage.py runcrons

Это делает работу. Каждый крон моделируется как класс (так что все его ОО), и каждый крон работает с разной частотой, и мы гарантируем, что один и тот же тип крона не работает параллельно (в случае, если самим кронам требуется больше времени, чем их частоте!)

Спасибо!

46
chachra

Если вы используете стандартную ОС POSIX, вы используете cron .

Если вы используете Windows, вы используете at .

Напишите команду управления Django 

  1. Выясните, на какой платформе они работают.

  2. Либо выполните соответствующую команду «AT» для ваших пользователей, или обновите crontab для ваших пользователей.

35
S.Lott

Интересное новое подключаемое приложение Django: Django-хронограф

Вам нужно только добавить одну запись cron, которая действует как таймер, и у вас есть очень хороший интерфейс администратора Django для запуска скриптов.

23
Van Gale

Посмотрите на Cron Django Poor Man's, который является приложением Django, которое использует спам-ботов, роботов индексации поисковых систем и т. П. Для запуска запланированных задач примерно через равные промежутки времени.

Смотрите: http://code.google.com/p/Django-poormanscron/

14
user41767

RabbitMQ и Celery имеют больше возможностей и возможностей для обработки задач, чем Cron. Если сбой задачи не является проблемой, и вы думаете, что будете обрабатывать сломанные задачи в следующем вызове, то Cron достаточно.

Celery & AMQP позволит вам обработать неработающую задачу и будет снова выполняться другим работником (сотрудники Celery ожидают выполнения следующей задачи), пока не будет достигнут атрибут max_retries задачи. Вы даже можете вызывать задачи при сбое, например, регистрировать сбой или отправлять электронное письмо администратору после достижения max_retries.

И вы можете распространять серверы Celery и AMQP, когда вам нужно масштабировать ваше приложение.

9
Ravi Kumar

Предложение Брайана Нила о запуске команд управления через cron работает хорошо, но если вы ищете что-то более надежное (но не такое сложное, как Celery), я бы заглянул в такую ​​библиотеку, как Kronos :

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass
9
Johannes Gorset

Я лично использую cron, но Jobs Scheduling parts of Django-extensions выглядит интересно.

8
Van Gale

Поместите следующее в начало вашего файла 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
6
Matt McCormick

Некоторое время назад у меня было точно такое же требование, и в итоге я решил его с помощью 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

Надеюсь, это кому-нибудь поможет!

6
PhoenixDev

Я просто подумал об этом довольно простом решении:

  1. Определите функцию представления do_work (req, param), как если бы вы работали с любым другим представлением, с отображением URL, возвращайте HttpResponse и так далее.
  2. Настройте задание cron с вашими настройками синхронизации (или с помощью AT или запланированных задач в Windows), которое запускает curl http: // localhost/your/mapped/url? Param = value.

Вы можете добавить параметры, но просто добавив параметры в URL.

Скажите мне, что вы, ребята, думаете.

[Update] Теперь я использую команду runjob из Django-extensions вместо curl.

Мой cron выглядит примерно так:

@hourly python /path/to/project/manage.py runjobs hourly

... и так далее ежедневно, ежемесячно и т. д. Вы также можете настроить его для запуска определенной работы.

Я нахожу это более управляемым и более чистым. Не требует привязки URL к представлению. Просто определите свой класс работы и crontab, и все готово.

6
Michael

Хотя Airflow не является частью Django, это более свежий проект (по состоянию на 2016 год), который полезен для управления задачами.

Airflow - это система автоматизации и планирования рабочих процессов, которую можно использовать для создания и управления конвейерами данных. Веб-интерфейс предоставляет разработчику ряд возможностей для управления и просмотра этих конвейеров.

Воздушный поток написан на Python и построен с использованием Flask.

Airflow был создан Максимом Бочемином в Airbnb и открыт с весны 2015 года. Он присоединился к программе инкубации Apache Software Foundation зимой 2016 года. Вот страница проекта Git и некоторые дополнения справочная информация ,.

6
Alexander

после части кода я могу написать что угодно, как и мои 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/

4
xiaohei

Вы обязательно должны проверить Django-q! Он не требует дополнительной настройки и, возможно, имеет все необходимое для решения любых производственных проблем коммерческих проектов.

Он активно развивается и очень хорошо интегрируется с Django, Django ORM, mongo, redis. Вот моя конфигурация:

# 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,
},
}
2
saran3h

У меня было что-то похожее с твоей проблемой сегодня.

Я не хотел, чтобы он обрабатывался сервером через cron (и большинство библиотек в итоге были просто помощниками cron).

Итак, я создал модуль планирования и прикрепил его к init .

Это не лучший подход, но он помогает мне хранить весь код в одном месте, а его выполнение связано с основным приложением.

2
Fabricio Buzeto

Да, метод выше, так здорово. И я попробовал некоторые из них. Наконец, я нашел такой метод:

    from threading import Timer

    def sync():

        do something...

        sync_timer = Timer(self.interval, sync, ())
        sync_timer.start()

Так же, как Рекурсивный .

Хорошо, я надеюсь, что этот метод может удовлетворить ваши требования. :)

2
Ni Xiaoni

Я использую сельдерей для создания своих периодических заданий. Сначала вам нужно установить его следующим образом:

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
1
David Felipe Camargo Polo

Я не уверен, что это будет полезно для всех, так как я должен был предоставить другим пользователям системы для планирования заданий, не предоставляя им доступ к фактическому планировщику задач сервера (windows), я создал это приложение многократного использования.

Обратите внимание, что пользователи имеют доступ к одной общей папке на сервере, где они могут создавать необходимые файлы command/task/.bat. Эта задача может быть запланирована с помощью этого приложения.

Имя приложения Django_Windows_Scheduler

Скриншот:  enter image description here

1
just10minutes

Более современным решением (по сравнению с Celery) является Django Q: https://Django-q.readthedocs.io/en/latest/index.html

Он имеет отличную документацию и легко прогуливается. Поддержка Windows отсутствует, поскольку Windows не поддерживает разветвление процессов. Но это прекрасно работает, если вы создаете свою среду разработки, используя подсистему Windows для Linux. 

1
devdrc

Если вы хотите что-то более надежное, чем Celery, попробуйте TaskHawk, построенное поверх AWS SQS/SNS.

См .: http://taskhawk.readthedocs.io

0
Sriram

Простой способ - написать собственную команду Shell, см. Документация Django и выполнить ее с помощью cronjob в linux. Однако я очень рекомендую использовать брокер сообщений, такой как RabbitMQ в сочетании с сельдереем. Может быть, вы можете взглянуть на Это учебник

0
Hamfri

Для простых докеризованных проектов я не мог найти подходящий ответ.

Поэтому я написал очень скромное решение без необходимости использования внешних библиотек или триггеров, которое работает само по себе. Не требуется внешний os-cron, он должен работать в любой среде.

Это работает путем добавления промежуточного программного обеспечения: middleware.py 

import threading

def should_run(name, seconds_interval):
    from application.models import CronJob
    from Django.utils.timezone import now

    try:
        c = CronJob.objects.get(name=name)
    except CronJob.DoesNotExist:
        CronJob(name=name, last_ran=now()).save()
        return True

    if (now() - c.last_ran).total_seconds() >= seconds_interval:
        c.last_ran = now()
        c.save()
        return True

    return False


class CronTask:
    def __init__(self, name, seconds_interval, function):
        self.name = name
        self.seconds_interval = seconds_interval
        self.function = function


def cron_worker(*_):
    if not should_run("main", 60):
        return

    # customize this part:
    from application.models import Event
    tasks = [
        CronTask("events", 60 * 30, Event.clean_stale_objects),
        # ...
    ]

    for task in tasks:
        if should_run(task.name, task.seconds_interval):
            task.function()


def cron_middleware(get_response):

    def middleware(request):
        response = get_response(request)
        threading.Thread(target=cron_worker).start()
        return response

    return middleware

models/cron.py:

from Django.db import models


class CronJob(models.Model):
    name = models.CharField(max_length=10, primary_key=True)
    last_ran = models.DateTimeField()

settings.py:

MIDDLEWARE = [
    ...
    'application.middleware.cron_middleware',
    ...
]
0
y-spreen