Django - 什么时候进行查询?

时间:2013-05-26 00:19:12

标签: python mysql django

我想尽量减少我的应用程序所做的数据库查询的数量,并且我更熟悉Django的ORM。我想知道,执行查询的情况是什么。

例如,这种格式与我正在寻找的答案一致(例如,目的,据我所知不准确):

  • Model.objects.get()
    • 始终启动查询
  • Model.objects.filter()
    • 如果对象仅为空,则启动查询
  • (...)

我假设curried过滤操作永远不会发出额外的请求,但是从文档中看起来像filter()确实会产生数据库请求,如果它是第一个被调用的东西。

2 个答案:

答案 0 :(得分:2)

请参阅Django关于何时评估查询集的文档:https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated

在这种情况下评估意味着执行查询。这主要发生在您尝试访问结果时,例如。在其上调用list()len()或迭代结果时。

示例中的

get()不返回查询集而是返回模型对象,因此会立即对其进行求值。

答案 1 :(得分:2)

如果您正在使用测试用例,则可以使用django TestCase中包含的自定义断言:assertNumQueries()

示例:

with self.assertNumQueries(2):
    x = SomeModel.objects.get(pk=1)
    y = x.some_foreign_key_in_object

如果预期的查询数量错误,您会看到表单中的断言失败消息:

Num queries (expected - actual):
    2 : 5

在此示例中,即使没有显式查询(get,filter,exclude等),外键也会导致其他查询。

出于这个原因,我会使用一种实用的方法:测试或记录,而不是尝试学习django应该查询的每种情况。


如果你不使用单元测试,你可以使用这个打印django发送的实际SQL语句的其他方法,这样你就可以了解查询的复杂性,而不仅仅是查询的数量: / p>

DEBUG设置必须设置为True

from django.db import connection

x = SomeModel.objects.get(pk=1)
y = x.some_foreign_key_in_object

print connection.queries

打印将显示查询字典:

[
 {'sql': 'SELECT a, b, c, d ... FROM app_some_model', 'time': '0.002'},
 {'sql': 'SELECT j, k, ... FROM app_referenced_model JOIN ... blabla ', 
      'time': '0.004'}
]
connection.queries上的

Docs

当然,您也可以将两种方法结合使用,并在测试用例中使用print connection.queries