关于python:Django后台任务

Django Background Task

我需要在Django中每隔几分钟填充一个SQLite数据库,但我想提供过时的数据,直到数据可供数据库更新。 (即我不想阻止收集数据;我唯一可以阻止的是数据库是否存在锁定,在此期间我别无选择。)

我也不想安装单独的程序或库。

我如何设置另一个可以在一堆模型上调用save()的线程,而不会遇到线程问题?


如果您正在寻找一种轻量级解决方案,只需在后台执行操作而不是完整的任务管理系统,请查看django-utils。除其他外,它包括一个@async函数装饰器,它将使函数在一个单独的线程中异步执行。

像这样使用它:

1
2
3
4
5
6
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太多,您只需下载它并在项目中包含一些必需的文件即可。


芹菜。

Celery is an asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.

Celery is written in Python, but the protocol can be implemented in any language. It can also operate with other languages using webhooks.


只是对John Lehmann的回答进行了快速更新:django-background-task没有维护,与更新的Django版本不兼容。我们不久前更新并扩展了新功能,并在Github上维护了新的向后兼容软件包。可以从PyPI下载或安装新的django-background-tasks应用程序。


取决于您是否需要从读者的角度看更新看起来是原子的。如果您不介意将旧数据和新数据放在一起,只需创建一个填充数据的自定义管理命令,然后每隔几分钟从cron运行一次。

如果你需要它看起来是原子的,通过django.db.transaction将所有写入包装在一个SQLite事务中应该可能为你提供必要的锁。


Django Background Task是Django的数据库支持的工作队列,松散地基于Ruby的DelayedJob库。

你装饰函数来创建任务:

1
2
3
4
5
@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')

虽然你仍然需要安排这些任务的东西。一些好处包括自动重试失败的任务,以及为正在运行的任务设置最长持续时间。

这确实涉及另一个依赖,但对于没有这种限制的一些读者可能是有用的。


我有同样的问题,但不想运行像芹菜这样的服务来解决问题。

我在linux系统上找到了posix_spawn。您可以编写在完整的django环境中运行的manage.py命令。这些命令可以在此项目的后台执行。

如果您需要在运行期间将数据传回网站,我使用memcached。

https://github.com/lukedupin/django_posix_spawn