Как получить первую страницу результатов для нескольких вещей в одном запросе - PullRequest
0 голосов
/ 27 мая 2018

Проблему немного сложно объяснить, но я сделаю все возможное.Я создаю сервер GraphQL в Django (используя Graphene), и отчасти это необходимо для пакетной обработки запросов к базе данных, чтобы избежать проблем n + 1.Это означает, что, скажем, при выборке набора событий, а не по одному запросу для каждого идентификатора события, мы делаем один запрос с where id in (...).

. Я пытаюсь добиться того же с помощью списков.Мой непосредственный вариант использования - у каждого события есть место проведения, и я хочу получить следующие 5 (это произвольно) событий для каждого места только одним запросом.

(Примечание: для полного обоснования этого, Я недавно написал статью )

Запрос PostgreSQL, который я придумал, таков:

SELECT
    *
FROM (
    SELECT
        *,
        ROW_NUMBER()
        OVER (PARTITION BY
                venue_id
            ORDER BY
                starts_at,
                ends_at,
                id) AS row_index
        FROM
            events_event
        WHERE
            starts_at >= '2018-05-20') x
    WHERE
        row_index <= 5

Я не думаю Мне понадобятся описания дел, потому что я не думаю, что существует реальная необходимость иметь возможность группировать последующие страницы - только начальные.

Так что у меня есть несколько вопросовоб этом:

  1. Есть ли лучший способ написания этого запроса?

  2. Это предпочтительнее, чем запускать несколько (реально между 10 и 30) параллельно выполняет запросы, чтобы сделать это обычным способом?

  3. Как мне выполнить этот запрос с помощью ORM Django (без перехода на сырой SQL)?

Третий вопрос - тот, над которым я бьюсь головой, потому что ORM кажется прОвидим все необходимые строительные блоки (я использую Django 2.0), но я не могу понять, как собрать их все вместе.

Это то, что я до сих пор использую Django:

Event.objects.annotate(
    row_number=Window(
        expression=RowNumber(), 
        partition_by=[F('venue_id')], 
        order_by=[F('starts_at').asc(), F('ends_at').asc(), F('id').asc()]
    )
)

Но мне не удалось найти способ фильтрации по row_number, потому что я не хочу возвращать все - только первые 5. Когда я пытаюсь сделать следующее, Django говорит мне, что фильтрация не разрешенаОконные пункты:

Event.objects.annotate(
    row_number=Window(
        expression=RowNumber(), 
        partition_by=[F('venue_id')], 
        order_by=[F('starts_at').asc(), F('ends_at').asc(), F('id').asc()]
    )
).filter(row_number__lte=5)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...