QuerySet 缓存:在过滤器被触发后执行 get

发布于 2024-11-06 16:47:08 字数 306 浏览 1 评论 0原文

以下代码将执行多少数据库查询:

q = SomeModel.objects.filter(pk__in=ids)
print q    # The actual query is executed and the result 
           # set evaluated
m = q.get(pk=ids[0])
print m    # Does it reuse the evaluated result set 
           # or does it hit the database the second time?

How many database queries will be executed for the following code:

q = SomeModel.objects.filter(pk__in=ids)
print q    # The actual query is executed and the result 
           # set evaluated
m = q.get(pk=ids[0])
print m    # Does it reuse the evaluated result set 
           # or does it hit the database the second time?

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

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

发布评论

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

评论(1

千鲤 2024-11-13 16:47:08

由于查询集是惰性评估的,如果您执行以下操作:

q = SomeModel.objects.filter(pk__in=ids)

...立即执行(即,不使用print):

m = q.get(pk=ids[0])

您最终将得到一个 SQL 查询。它将第一个查询与第二个查询AND在一起。以这种方式继续添加查询集是安全的。在 Django 1.3 中,日志记录得到了改进,您可以在交互式控制台中获得良好的日志记录:

>>> import logging
>>> l = logging.getLogger('django.db.backends')
>>> l.setLevel(logging.DEBUG)
>>> l.addHandler(logging.StreamHandler())

一旦执行实际查询,它将立即为您提供此类调试信息:

(0.013) SELECT "someapp_somemodel"."id", "someapp_somemodel"."question", "someapp_somemodel"."pub_date" FROM "someapp_somemodel" WHERE ("someapp_somemodel"."id" IN (0, 1) AND "someapp_somemodel"."id" = 0 ); args=(0, 1, 0)

不要在 a 上使用 get过滤查询集。如果您想要的模型在查询集中,请使用 Python 表达式(例如列表理解或过滤器等)从查询集中获取模型实例,并避免再次访问数据库时间(或者如果您迭代 id 列表,则需要多次)。

Since querysets are evaluated lazily if you do:

q = SomeModel.objects.filter(pk__in=ids)

...immediately folllowed by (i.e., without using print):

m = q.get(pk=ids[0])

You'll end up with one SQL query. It'll AND together the first query with the second. It's safe to continue adding to querysets this way. In Django 1.3 the logging is revamped and you can get nice logging in the interactive console:

>>> import logging
>>> l = logging.getLogger('django.db.backends')
>>> l.setLevel(logging.DEBUG)
>>> l.addHandler(logging.StreamHandler())

Which will give you this sort of debugging info as soon as an actual query is executed:

(0.013) SELECT "someapp_somemodel"."id", "someapp_somemodel"."question", "someapp_somemodel"."pub_date" FROM "someapp_somemodel" WHERE ("someapp_somemodel"."id" IN (0, 1) AND "someapp_somemodel"."id" = 0 ); args=(0, 1, 0)

Don't use get on a filtered queryset. If the model you want is in your queryset, use a Python expression (like a list comprehension or filter or such) to get the model instance out of your queryset, and avoid hitting the database at all a second time (or many more times if you iterate over a list of id's).

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