我想澄清一些事情,以便我可以通过psycopg2适配器优化我的Django ORM查询到Postgres。
比如说我有三个模型:
from django.db import models
class City(models.Model):
#
pass
class Person(models.Model):
hometown = models.ForeignKey(City)
class Book(models.Model):
author = models.ForeignKey(Person)
现在让我们进行以下查询:
book = Book.objects.get(pk = 4)
现在,如果我想知道作者的原始ID,我需要做的就是这个
>>> raw_id = book.author_id
>>> print raw_id
3
我的问题是,book.author_id是否会对数据库进行另一次点击,还是只是从内存中获取它,因为它已经从get查询中获取了?根据我的理解,这个查询应该只有一次旅行正确吗?
答案 0 :(得分:4)
你是对的,book.author_id
没有在数据库上再次命中,外键ID存储在书中。如果您使用DEBUG=True
设置转到shell,您可以自己查看:
>>> from django.db import connection
>>> connection.queries
[]
>>> book = Book.objects.get(pk=4)
>>> connection.queries
[{u'sql': u'SELECT "yourapp_book"."id", "yourapp_book"."author_id" FROM "yourapp_book" WHERE "yourapp_book"."id" = 4 ',
u'time': u'0.003'}]
>>> book.author_id
7
>>> connection.queries
[{u'sql': u'SELECT "yourapp_book"."id", "yourapp_book"."author_id" FROM "yourapp_book" WHERE "yourapp_book"."id" = 4 ',
u'time': u'0.003'}]
>>> book.author
<Author: Mark Twain>
>>> connection.queries
[{u'sql': u'SELECT "yourapp_book"."id", "yourapp_book"."author_id" FROM "yourapp_book" WHERE "yourapp_book"."id" = 4 ',
u'time': u'0.003'},
{u'sql': u'SELECT "yourapp_author"."id", "yourapp_author"."name" FROM "yourapp_author" WHERE "yourapp_author"."id" = 7 ',
u'time': u'0.001'}]
connection.queries
列出了在DEBUG
打开时通过django shell中的ORM发送的所有SQL查询。请注意,即使在执行book.author_id
之后也只进行了一次查询,但是当我们执行book.author
时会进行第二次查询,因为django必须返回数据库才能获取要显示的作者姓名。
您可以通过book = Book.objects.select_related('author').get(pk=4)
选择图书来避免第二次数据库查询。
>>> connection.queries
[]
>>> book = Book.objects.select_related('author').get(pk=4)
>>> connection.queries
[{u'sql': u'SELECT "yourapp_book"."id", "yourapp_book"."author_id",
"yourapp_author"."id", "yourapp_author"."name"
FROM "yourapp_book" LEFT OUTER JOIN "yourapp_author" ON
( "yourapp_book"."author_id" = "yourapp_author"."id" ) WHERE "yourapp_book"."id" = 4 ',
u'time': u'0.003'}]
>>> book.author
<Author: Mark Twain>
>>> connection.queries
[{u'sql': u'SELECT "yourapp_book"."id", "yourapp_book"."author_id",
"yourapp_author"."id", "yourapp_author"."name"
FROM "yourapp_book" LEFT OUTER JOIN "yourapp_author" ON
( "yourapp_book"."author_id" = "yourapp_author"."id" ) WHERE "yourapp_book"."id" = 4 ',
u'time': u'0.003'}]
我还应该注意,为了调试在测试期间在运行的django应用程序中实际进行的查询数量,工具django-debug-toolbar是非常宝贵的。