20

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

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

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

4

6 回答 6

19

如果你正在寻找一个轻量级的解决方案,只在后台执行一些东西,而不是一个成熟的任务管理系统,看看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 functionfor background 或load_data用于阻止执行的普通函数。

只需确保安装 2.0 之前的版本,因为它缺少 @async 装饰器。

注意:如果安装 django-utils 太多了,你可以简单地下载它并在你的项目中包含几个必需的文件。

于 2012-02-11T09:04:15.140 回答
17

芹菜

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

Celery 是用 Python 编写的,但该协议可以用任何语言实现。它还可以使用 webhook 与其他语言一起运行。

于 2011-07-06T22:12:51.603 回答
6

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

于 2015-12-09T13:39:37.027 回答
5

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

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

于 2011-07-06T20:56:14.373 回答
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')

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

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

于 2014-12-17T19:22:34.510 回答
1

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

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

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

https://github.com/lukedupin/django_posix_spawn

于 2015-09-11T21:18:43.987 回答