Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 5, 2017 16:42:23

Jimbo
Зарегистрирован: 2016-04-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Django агрегация

Всем доброго времени суток.
Перейду сразу к сути, можно ли, допустим, такой список queryset'ов объединить в один запрос:

 Car.objects.filter(engine=0).order_by('-birthdate')[:10]
Car.objects.filter(engine=1).order_by('-birthdate')[:10]
Car.objects.filter(engine=2).order_by('-birthdate')[:10]
Car.objects.filter(engine=3).order_by('-birthdate')[:10]

Про annotate читал, пробовал, но к данной задаче применить не получилось.
Пробовал сделать через raw обычным sql-запросом - да, работает.
НО! Можно ли это сделать именно средствами ORM?

Офлайн

#2 Апрель 5, 2017 19:05:36

VadimK
Зарегистрирован: 2013-07-03
Сообщения: 199
Репутация: +  16  -
Профиль   Отправить e-mail  

Django агрегация

 Car.objects.filter(engine__in=[0,1,2,3]).order_by('-birthdate')[:10]
Или же просьба показать сам sql запрос, что бы понять, что надо в результате.

Офлайн

#3 Апрель 5, 2017 20:25:49

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Django агрегация

VadimK
Да понятно же, что надо автору: десять самых новых машин с двигателем 1, десять с двигателем 2 и т.д. Ваш запрос сначала отсортирует, а потом пролимитит, а надо наоборот. Один запрос можно сделать так (если вспомнить, что запросы не выполняются, пока их не вызвать)

         sub1 = Car.objects.filter(engine=0).order_by('-birthdate').only("id")[:10]
        sub2 = Car.objects.filter(engine=1).order_by('-birthdate').only("id")[:10]
        sub3 = Car.objects.filter(engine=2).order_by('-birthdate').only("id")[:10]
        sub4 = Car.objects.filter(engine=3).order_by('-birthdate').only("id")[:10]
        cars = Car.objects.filter(Q(id__in=sub1) | Q(id__in=sub2) | Q(id__in=sub3)| Q(id__in=sub4))



Отредактировано FishHook (Апрель 5, 2017 20:26:16)

Офлайн

#4 Апрель 6, 2017 13:27:53

Jimbo
Зарегистрирован: 2016-04-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Django агрегация

FishHook
Наверное отличное решение, только почему-то .only(“id”) возвращает не только id, который соответствует объекту в таблице БД, а некий объект “Car_Deferred_engine_birthdate165d2a59d66bcb6efd86fae72da58d9” в котором, как ни странно, есть и engine, и birthdate.

Отредактировано Jimbo (Апрель 6, 2017 13:28:12)

Офлайн

#5 Апрель 6, 2017 14:26:15

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Django агрегация

Jimbo
Наверное отличное решение, только почему-то .only(“id”) возвращает не только id, который соответствует объекту в таблице БД
Я ведь вам специально в скобках написал что запросы не выполняются, пока их не вызвать. sub1, sub2 и т.д. это не объект, соответствующий чему-то там в БД, а запрос. Если вы его использутете в другом запросе, то он становится подзапросом, если вы его попробуете выполнить, то есть прочитатете его циклом или кастанете к строке или сделаете с ним что-либо, то ОРМ полезет в БД, выполнит запрос и отобразит полученные данные на объекты модели. И да, в этих объектах будут все поля (ну а куда они денутся то?) только, они будут неинициализированы, и если вы попытаетесь их прочесть, то фреймворк снова полезет за ними в БД.

Если короче “только почему-то .only(“id”) возвращает не только id” - в моем примере он вообще ничего не возвращает, он не ходит в БД вообще и фигурирует лишь в итоговом запросе как подзапрос. Сделайте так

         sub1 = Car.objects.filter(engine=0).order_by('-birthdate').only("id")[:10]
        sub2 = Car.objects.filter(engine=1).order_by('-birthdate').only("id")[:10]
        sub3 = Car.objects.filter(engine=2).order_by('-birthdate').only("id")[:10]
        sub4 = Car.objects.filter(engine=3).order_by('-birthdate').only("id")[:10]
        cars = Car.objects.filter(Q(id__in=sub1) | Q(id__in=sub2) | Q(id__in=sub3)| Q(id__in=sub4))
        print cars.query 



Офлайн

#6 Апрель 6, 2017 14:57:25

Jimbo
Зарегистрирован: 2016-04-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Django агрегация

FishHook

Насчет того, что не выполняются я понял, просто я в отладке значения просматривал.
А просматривал я их за тем, что при выполнении строки

 cars = Car.objects.filter(Q(id__in=sub1) | Q(id__in=sub2) | Q(id__in=sub3)| Q(id__in=sub4))
всё время выпадает ошибка:
int() argument must be a string, a bytes-like object or a number, not 'Car_Deferred_engine_birthdate165d2a59d66bcb6efd86fae72da58d9'
Если я правильно понимаю, он хочет получить циферки, а получает набор объектов.


То ли лыжи не едут, то ли я не обутый)

Отредактировано Jimbo (Апрель 6, 2017 14:57:39)

Офлайн

#7 Апрель 6, 2017 16:42:25

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Django агрегация

Jimbo
Боюсь, что необутый



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version