我需要在Django中每隔几分钟填充一个SQLite数据库,但我想提供过时的数据,直到数据可供数据库更新。 (即我不想阻止收集数据;我唯一可以阻止的是数据库是否存在锁定,在此期间我别无选择。)
我也不想安装单独的程序或库。
我如何设置另一个可以在一堆模型上调用save()的线程,而不会遇到线程问题?
-
"我也不想安装单独的程序或库"通常是一项昂贵的政策。芹菜为您做到这一点。为什么不安装芹菜?
-
@ S.Lott:因为它将出现在某人的服务器上,我想尽量避免在服务器上倾倒东西。对于一个单独的线程来说,这不是有点矫枉过正吗?
-
"对于一个单独的线程来说,这不是有点矫枉过正吗?"不,"在服务器上倾倒东西"?一个安装是倾销?我不反对。你想要它工作,还是你想编写,测试和调试很多代码?
-
@ S.Lott:我希望它可以工作,但我不明白为什么我需要一个完整的库只是为了制作一个单独的线程。如果你能说服我,我就是为了它,但我现在似乎没有必要,特别是因为这是在Python(它似乎包括一个模块,比如,所有东西)。
-
可悲的是。这不是一个"简单的线程"。你一直这么说,但这是假的。如果你一直声称它是一个"简单的线程",那就没有"令人信服"了。如果它真的很简单,那你就已经做到了。
-
@ S.Lott:If it was actually simple, you would have done it already.嗯,我实际上是Python和Django的新手,所以我没想到它会那么困难;我只是觉得我不知道怎么做。我仍然不确定它的哪一部分需要库:它是数据库锁吗?是线程本身吗?或者是其他让事情变得复杂的事情,我忘记了?
-
你不能只生成一个新线程。 Django在Web服务器环境中运行,这意味着通常只在服务器收到请求时执行代码,这意味着代码应该快速执行并尽快完成,以避免占用Web服务器线程。此外,由于代码仅在收到请求时才执行,因此很难保证"每隔几分钟"就会发生一些事情。如果我是你,我会为此编写一个单独的python脚本,并通过cron运行。 Cron到处安装:-)
-
@Mehrdad:"好吧,我实际上是Python和Django的新手"。更有理由安装和使用几乎所有人都使用的标准解决方案:芹菜。考虑从问题中删除"也不想安装",因为这是一个非常非常糟糕的主意,特别是对于n00b。
-
@AHM:非常感谢你的信息,虽然我不确定我会走那条路。 :) @ S.Lott:您的评论就像告诉"n00b"安装Eclipse或Visual Studio,以便他可以制作他的第一个Hello,World程序。拥有一个IDE可能会有所帮助,但(1)它太过分了,(2)这个人会认为他总是需要一个IDE,(3)他永远不会知道这个建议背后的原因。所以,如果不是叫我n00b,你实际上告诉我为什么我不应该这样做(也许就像AHM那样?),那么我可能真的明白你的意思。
-
@Mehrdad:"这太过分了"错误。"这个人会认为他总是需要一个IDE"。什么?"他永远不会知道建议背后的原因"我一直试图解释,你一直拒绝解释。这并不简单。我有多少种不同的方式可以说出来?
-
@ S.Lott:是的,使用IDE编写小程序是过度的。非常矫枉过正。如果您认为使用Eclipse / Visual Studio /等。对编程是一个很好的介绍,的确,我可能永远都不会理解你对此的意思,所以它可能不值得争论。 :
-
@Mehrdad:IDE类比没有意义。即使有解释。它与使用芹菜的方式无法相提并论。请停止重复。
-
@ S.Lott:那么在那种情况下,我不需要争辩;谢谢你的意见。
-
@Mehrdad:使用像芹菜这样的插件就像使用RDBMS或使用Apache一样。这很重要。这与使用IDE完全不同。
如果您正在寻找一种轻量级解决方案,只需在后台执行操作而不是完整的任务管理系统,请查看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太多,您只需下载它并在项目中包含一些必需的文件即可。
-
异步导入错误
-
不幸的是,djutils似乎不再活跃。至少删除了readthedocs和github页面。
-
readOhedocs页面似乎仍然缺失,@ Olli,但github页面是可见的。
-
readthedocs链接是错误的:这里存在django-utils文档。
-
我尝试使用django-utils但它似乎与Django 1.8不兼容,不是吗?
-
我不能用Django 1.10做from djutils.decorators import async。它想导入已在Django 1.6中弃用的hashcompat。我想提交一份错误报告,但项目似乎已经死了:(
芹菜。
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事务中应该可能为你提供必要的锁。
-
我之前从未使用过cron,但是 - 除非我误解了这个 - 这不是一个完全独立的程序吗?这是否意味着我必须从我的服务器创建一个单独的,调用cron,并运行该程序来更新数据库?
-
cron是一个在linux,freebsd和osx后台运行的进程。请参阅:en.wikipedia.org/wiki/Cron。
-
@Amar:就像我之前所理解的那样,它是一个完全独立的程序......这意味着我需要为更新创建一个新程序。我不确定我会走那条路,但是+1,感谢你的想法。
-
@Mehrdad:几乎每个系统都有某种任务调度程序。类Unix的有cron,Windows有en.wikipedia.org/wiki/Task_Scheduler
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