Кэширование QuerySet: выполнение get после запуска фильтра - PullRequest
0 голосов
/ 11 мая 2011

Сколько запросов к базе данных будет выполнено для следующего кода:

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?

1 Ответ

1 голос
/ 11 мая 2011

Поскольку наборы запросов оцениваются лениво, если вы делаете:

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)

Не используйте get для отфильтрованного набора запросов. Если нужная модель находится в вашем наборе запросов, используйте выражение Python (например, понимание списка или filter или подобное), чтобы вывести экземпляр модели из вашего набора запросов и избежать повторного попадания в базу данных (или многих других). раз, если вы перебираете список идентификаторов).

...