Django背景任务

时间:2011-07-06 20:47:53

标签: python database django multithreading background-thread

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

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

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

6 个答案:

答案 0 :(得分:18)

如果您正在寻找一种轻量级解决方案,只需在后台执行内容而不是完整的任务管理系统,请查看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太多,你可以简单地download it并在项目中包含一些必需的文件。

答案 1 :(得分:16)

Celery

  

Celery是基于分布式消息传递的异步任务队列/作业队列。它专注于实时操作,但也支持调度。

     

Celery是用Python编写的,但协议可以用任何语言实现。它也可以使用webhooks与其他语言一起使用。

答案 2 :(得分:5)

取决于您是否需要从读者的角度看更新看起来是原子的。如果您不介意同时查看旧数据和新数据,只需创建一个填充数据的custom management command,然后每隔几分钟从cron运行一次。

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

答案 3 :(得分:5)

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

答案 4 :(得分:4)

Django Background Task是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 :(得分:1)

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

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

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

https://github.com/lukedupin/django_posix_spawn