Форум сайта python.su
1
Разбираюсь с Django. Написал что-то вроде
# Получить обекты модели MsgTxt, которые нам нужны
mt = MsgText.objects.filter(msg__page__name=page,lang__name=lang)
# Упаковать полученную информацию в словарь
out = {}
for ob in mt:
out[ob.msg.name] = ob.text
return out
SELECT ..... WHERE "multilang_msg"."id" = 14
Офлайн
0
стоит прочитать про
http://docs.djangoproject.com/en/dev/topics/db/queries/#querysets-are-lazy
ну и как возможный путь решения
http://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related
Офлайн
3
f_evgeny
Поискал и не нашел способа получить сразу все объекты одним SQL запросом
mt = list(MsgText.objects.filter(msg__page__name=page,lang__name=lang))
Офлайн
1
cybergrindПосмотрел, это не совсем то.
стоит прочитать про
http://docs.djangoproject.com/en/dev/topics/db/queries/#querysets-are-lazy
ну и как возможный путь решения
http://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related
Офлайн
1
regallЭто не то, количество запросов не уменьшается, просто генерятся они не в цикле, а во время выполнения list()f_evgeny
Поискал и не нашел способа получить сразу все объекты одним SQL запросомmt = list(MsgText.objects.filter(msg__page__name=page,lang__name=lang))
Офлайн
1
Короче, сделал так:
def get_msgs(self,page,lang):
from django.db import connection, transaction
cursor = connection.cursor()
cursor.execute("""
SELECT msg.name,mst.text
FROM multilang_msgtext AS mst, multilang_msg AS msg,
multilang_page AS mp, multilang_lang as ml
WHERE mst.lang_id=ml.id AND mst.msg_id=msg.id AND msg.page_id=mp.id
AND ml.name=%s AND mp.name=%s;
""",(lang,page))
out = {}
while(1):
row = cursor.fetchone()
if(row == None):
break
out[row[0]] = row[1]
return out
Количество Количество Среднее время
элементов запросов генерации страницы
Старый код: 12 13 ~300ms
Новый код: 12 1 ~150ms
Офлайн
0
ну судя по запросу это как раз и есть случай который описывается в ленивых кверисетах, дергается каждый раз объект из другой модели, и на каждый такой вызов выполняется запрос к базе данных.
Офлайн
2
f_evgenyНет.
Я правильно понимаю, что тут нужно испольpовать кастомный SQL запрос, не испольуя ORM?
Офлайн
1
Да дело-то не в том, что значения по ForeignKey тащатся отдельными запросами. Данный код должен вытыщить несколько строк таблицы. Дело в том, что код получается работает в два этапа:
1) Составляется довольно-таки грамотный запрос, учитывающий связи, и все, что нужно. Этот запрос возвращает итерабильный QuerySet.
2) При запросе во время очередной итерации следующего элемента, QuerySet генерирует ОДИН SQL запрос и тащит ОДНУ строку из таблицы, по ‘id’. И так каждый раз.
В случае, когда для формирования вебстраницы нужно из одной таблицы вытащить штук 50 строк, это все может быть затратным.
Если посмотреть в потроха, выглядит все это примерно так:
Первый запрос, возвращающий QuerySet
SELECT "multilang_msgtext"."id", "multilang_msgtext"."lang_id", "multilang_msgtext"."msg_id", "multilang_msgtext"."text" FROM "multilang_msgtext" INNER JOIN "multilang_lang"
ON ("multilang_msgtext"."lang_id" = "multilang_lang"."id") INNER JOIN "multilang_msg" ON ("multilang_msgtext"."msg_id" = "multilang_msg"."id")
INNER JOIN "multilang_page" ON ("multilang_msg"."page_id" = "multilang_page"."id")
WHERE ("multilang_lang"."name" = E'Russian' AND "multilang_page"."name" = E'site_header_1' )
.....
SELECT "multilang_msg"."id", "multilang_msg"."page_id", "multilang_msg"."msgnum", "multilang_msg"."name", "multilang_msg"."comment"
FROM "multilang_msg" WHERE "multilang_msg"."id" = 20
.....
Офлайн
2
Очевидно, что вы от нас почему-то скрываете питонячий код моделей и что по этом sql запросам ничего не понятно.
Офлайн