рамки для отдыха django аннотируют с помощью ArrayAgg и GROUP BY - PullRequest
0 голосов
/ 25 мая 2019

Я хотел бы использовать функцию django postgres ArrayAgg, но я также хотел бы использовать ее и с GROUP BY. Sql действительно легко написать, но я не смог заставить его работать с ORM или с сырым sql

SELECT field1, ARRAY_AGG(field2)
FROM table1
GROUP BY field1

с формой, я думаю, что-то вроде этого может работать

subquery = Subquery(
           models.Model1.objects
           .filter(field1=OuterRef('field1'))
           .values('field2')
           .aggregate(field3=ArrayAgg('field2'))
           .values('field3')
)
queryset = queryset.annotate(field3=subquery)

Но это не так с внешней ошибкой (я пробовал много перестановок)

и с помощью необработанного запроса я могу заставить его работать, но затем он возвращает все поля, которые я предполагаю, из-за RawQueryset, и такие вещи, как defer, не работают, поэтому все поля запрашиваются и возвращаются.

rawqueryset = models.Model1.objects.raw(
    'SELECT m.id, t.field1, t.field3 '
    'FROM ('
        'SELECT field1, array_agg(field2) as field3 '
        'FROM app_table1 '
        'GROUP BY frame_id '
    ') t LEFT OUTER JOIN app_table m ON m.field1 = t.frame_id',
    []
)
serializer = serializers.Model1(rawqueryset, many=True)
return Response(serializer.data)

Есть ли способ сделать это?

1 Ответ

0 голосов
/ 18 июля 2019

Мне удалось заставить его работать, используя raw sql

rawqueryset = models.Model1.objects.raw(
    'SELECT m.id, t.field1, t.field3 '
    'FROM ('
        'SELECT field1, array_agg(field2) as field3 '
        'FROM app_table1 '
        'GROUP BY frame_id '
    ') t LEFT OUTER JOIN app_table m ON m.field1 = t.frame_id',
    []
)
serializer = serializers.Model1(rawqueryset, many=True, context={'request': request})
return Response(serializer.data)

Чего не хватало, так это добавления объекта запроса в переданный контекст.

...