在 django 查询集上使用 iterator()
我最近遇到了一些奇怪的行为,需要检查我的理解。
我在模型中使用一个简单的过滤器,然后迭代结果。
例如
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 memoryNote that using
iterator()
on a QuerySet which has already been evaluated will force it to evaluate again, repeating the query.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是查询集必须工作的方式。迭代查询集应该会给出数据库返回的每条记录。调试您的代码。你会发现错误的,否则再调试一下。
在 REPL 中检查很容易。运行
manage.py shell
: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
: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 theQuerySet
level.https://docs.djangoproject.com/en/dev/ref/models/querysets/