Основная задача Django
Мне нужно заполнить базу данных SQLite каждые несколько минут в Django, но я хочу использовать устаревшие данные, пока данные не будут доступны для базы данных, которая будет обновлена. (т.е. я не хочу блокировать сбор данных, единственный раз, когда я могу заблокировать, есть блокировка в базе данных, во время которой у меня нет выбора.)
Я также не хочу устанавливать отдельную программу или библиотеку.
Как мне настроить другой поток, который мог бы вызвать save()
на кучу моделей, без проблем с потоками?
Ответы
Ответ 1
Если вы ищете легкое решение для простого выполнения материалов в фоновом режиме, а не полномасштабной системы управления задачами, посмотрите django-utils. Он включает, помимо прочего, @async декоратор функции, который заставит функцию выполнять асинхронно в отдельном потоке.
Используйте его следующим образом:
from djutils.decorators import async
@async
def load_data_async():
# this will be executed in a separate thread
load_data()
Затем вы можете вызвать либо load_data_async function
для фона, либо обычную функцию load_data
для блокировки выполнения.
Просто установите версию до версии 2.0, так как в ней не хватает декоратора @async.
Примечание. Если даже установка django-utils будет слишком большой, вы можете просто загрузить его и включить несколько требуемых файлов в свой проект.
Ответ 2
Celery.
Сельдерей - это очередь асинхронной очереди задач/заданий, основанная на распределенной передаче сообщений. Он ориентирован на работу в реальном времени, но также поддерживает планирование.
Сельдерей написан на Python, но протокол может быть реализован на любом языке. Он также может работать с другими языками, используя webhooks.
Ответ 3
Зависит от того, нужно ли вам обновлять, чтобы смотреть на атомы с точки зрения читателей. Если вы не возражаете видеть старые и новые данные вместе, просто создайте команду пользовательского управления, которая заполняет данные и запускает их каждые несколько минут с cron.
Если вам нужно, чтобы он выглядел атомарным, обертывая все записи в одной транзакции SQLite через django.db.transaction, вероятно, должны предоставить вам необходимые блокировки.
Ответ 4
Задача Django Background - это рабочая очередь с поддержкой базы данных для Django, свободно основанная на библиотеке Ruby DelayedJob.
Вы украшаете функции для создания задач:
@background(schedule=60)
def notify_user(user_id):
# lookup user by id and send them a message
user = User.objects.get(pk=user_id)
user.email_user('Here is a notification', 'You have been notified')
Хотя вам все еще нужно что-то, что планирует эти задачи. Некоторые преимущества включают автоматические повторы неудачных задач и максимальную продолжительность выполняемой задачи.
Это связано с другой зависимостью, но может быть полезно для некоторых читателей без этого ограничения.
Ответ 5
Просто быстрое обновление ответа Джона Леманна: django-background-task осталась без изменений и несовместима с новой версией Django. Мы обновили и расширили его новыми функциями некоторое время назад и поддерживаем новый обратный совместимый пакет на Github. Новое приложение django-background-tasks можно загрузить или установить из PyPI.
Ответ 6
У меня была такая же проблема, но я не хотел запускать службу, например, сельдерей, чтобы решить эту проблему.
Я нашел posix_spawn для Linux-систем. Вы можете написать команды manage.py, которые запускаются в вашей полной среде django. Эти команды могут быть выполнены в фоновом режиме с помощью этого проекта.
Если вам нужно передать данные обратно на сайт во время прогона, я использую memcached.
https://github.com/lukedupin/django_posix_spawn