在 django 查询集上使用 iterator()

发布于 2024-10-18 13:20:47 字数 722 浏览 3 评论 0原文

我最近遇到了一些奇怪的行为,需要检查我的理解。

我在模型中使用一个简单的过滤器,然后迭代结果。

例如

allbooks = Book.objects.filter(author='A.A. Milne')

for book in allbooks:
   do_something(book)

,奇怪的是,它只返回部分书籍列表。

然而,当使用相同的代码并使用 iterator() 时,这似乎工作得很好。

for book in allbooks.iterator():
    do_something(book)

知道为什么吗?

ps 我确实浏览了 Django 文档,但看不到查询集如何在其他地方缓存......

迭代器() 评估 QuerySet(通过执行查询)并返回结果的迭代器。 QuerySet 通常会在内部缓存其结果,以便重复计算不会导致额外的查询; iterator() 将直接读取结果,而不在 QuerySet 级别进行任何缓存。对于返回大量对象的 QuerySet,这通常会带来更好的性能并显着减少内存

请注意,在已评估的 QuerySet 上使用 iterator() 将强制它再次评估,从而重复查询。

I came across some strange behaviour recently, and need to check my understanding.

I'm using a simple filter in the model and then iterating over the results.

e.g.

allbooks = Book.objects.filter(author='A.A. Milne')

for book in allbooks:
   do_something(book)

oddly, it was returning only a partial list of books.

However, when using the same code and using iterator(), this seems to work well.

i.e.

for book in allbooks.iterator():
    do_something(book)

Any idea why?

p.s. I did look through the Django documentation, but can't see how the queryset would be cached already anywhere else...

iterator()
Evaluates the QuerySet (by performing the query) and returns an iterator over the results. A QuerySet typically caches its results internally so that repeated evaluations do not result in additional queries; iterator() will instead read results directly, without doing any caching at the QuerySet level. For a QuerySet which returns a large number of objects, this often results in better performance and a significant reduction in memory

Note that using iterator() on a QuerySet which has already been evaluated will force it to evaluate again, repeating the query.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨夜星沙 2024-10-25 13:20:47

奇怪的是,它只返回了部分内容
书籍清单。

这不是查询集必须工作的方式。迭代查询集应该会给出数据库返回的每条记录。调试您的代码。你会发现错误的,否则再调试一下。

在 REPL 中检查很容易。运行manage.py shell

from app.models import Model
for o in Model.objects.filter(fieldname="foo"): print o

#Let's see DB query
from django.db import connection
print(connection.queries)

oddly, it was returning only a partial
list of books.

That's not how the queryset must work. Iterating over queryset should give you every record returned by your database. Debug your code. You'll find the error, otherwise debug it again.

It's easy to check in the REPL. Run manage.py shell:

from app.models import Model
for o in Model.objects.filter(fieldname="foo"): print o

#Let's see DB query
from django.db import connection
print(connection.queries)
各空 2024-10-25 13:20:47

QuerySet 通常会在内部缓存其结果,以便重复计算不会导致额外的查询。相比之下,iterator() 将直接读取结果,而不在 QuerySet 级别进行任何缓存。

https://docs.djangoproject.com/en/dev/ref/models /查询集/

A QuerySet typically caches its results internally so that repeated evaluations do not result in additional queries. In contrast, iterator() will read results directly, without doing any caching at the QuerySet level.

https://docs.djangoproject.com/en/dev/ref/models/querysets/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文