Как я могу добавить фильтр для всех наборов запросов в конце sql-запроса? - PullRequest
0 голосов
/ 26 ноября 2018

Если я добавлю фильтр в диспетчере, SQL-запрос к базе данных будет слишком длинным, потому что мой фильтр будет в начале SQL-запроса.

Мне нужно запустить этот фильтр в конце, послевсе остальные фильтры и изменения были применены.

Текущий набор запросов:

links = Link.objects.all().filter_deleted()
links = links.filter(linkname='linkname', left_uuid__in=all_uuids)
links = links.filter(left_type='type')
links = links.values_list('left_uuid', 'right_uuid', 'right_type')

SQL-запрос после компиляции queruset:

SELECT "baseobj_link"."left_uuid", "baseobj_link"."right_uuid", "baseobj_link"."right_type_id"
FROM "baseobj_link"
WHERE (
    "baseobj_link"."id" IN (
        SELECT DISTINCT ON (U0."linkname", U0."left_uuid", U0."right_uuid") U0."id" AS Col1
        FROM "baseobj_link" U0
        WHERE U0."config_id" IN (2848)
        ORDER BY U0."linkname" ASC, U0."left_uuid" ASC, U0."right_uuid" ASC, U0."domain_level" ASC, U0."config_id" DESC, U0."is_deleted" DESC
    ) AND
    "baseobj_link"."is_deleted" = false AND
    "baseobj_link"."linkname" = 'linkname' AND
    "baseobj_link"."left_uuid" IN (
        SELECT V0."uuid" AS Col1
        FROM "structure_cgw" V0
        WHERE (
            V0."id" IN (
                SELECT DISTINCT ON (U0."uuid") U0."id" AS Col1
                FROM "structure_cgw" U0
                WHERE U0."config_id" IN (2848)
                ORDER BY U0."uuid" ASC, U0."domain_level" DESC, U0."config_id" DESC
            ) AND
            V0."is_deleted" = false
        )
    ) AND
    "baseobj_link"."left_type_id" = 6
);
args=(2848, False, 'linkname', 2848, False, 6)

Часть, сгенерированная filter_deleted () :

"baseobj_link"."id" IN (
    SELECT DISTINCT ON (U0."linkname", U0."left_uuid", U0."right_uuid") U0."id" AS Col1
    FROM "baseobj_link" U0
    WHERE U0."config_id" IN (2848)
    ORDER BY U0."linkname" ASC, U0."left_uuid" ASC, U0."right_uuid" ASC, U0."domain_level" ASC, U0."config_id" DESC, U0."is_deleted" DESC
)

Необходимо добавить этот код в конце всех запросовдля этой модели, так что это не простая задача.

Как это можно решить наиболее эффективно?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

В своей модели queryset'а дополнительно сохранен набор запросов без filter_deleted и переопределяемый метод _filter_or_exclude, который может вызвать _filter_or_exclude у хранимого queryset'а, а потом уже уже filter_deleted._Filter_or_exclude, а когда filter_deleted.

0 голосов
/ 26 ноября 2018

Похоже, вы пытаетесь запустить фильтр для подзапроса.Поэтому поместите весь код, который вы хотите запустить, в подзапрос.Затем запустите фильтры, которые вы хотите применить после того, как этот запрос завершится в последнем фильтре.

будет выглядеть примерно так:

SELECT *
FROM    (
        SELECT "baseobj_link"."left_uuid", "baseobj_link"."right_uuid", "baseobj_link"."right_type_id"
        FROM "baseobj_link"
        WHERE
            "baseobj_link"."is_deleted" = false AND
            "baseobj_link"."linkname" = 'cgw_vhost' AND
            "baseobj_link"."left_uuid" IN (
                SELECT V0."uuid" AS Col1
                FROM "structure_cgw" V0
                WHERE (
                    V0."id" IN (
                        SELECT DISTINCT ON (U0."uuid") U0."id" AS Col1
                        FROM "structure_cgw" U0
                        WHERE U0."config_id" IN (2848)
                        ORDER BY U0."uuid" ASC, U0."domain_level" DESC, U0."config_id" DESC
                    ) AND
                    V0."is_deleted" = false
                )
            AND "baseobj_link"."left_type_id" = 6
        ) AS t1
WHERE t1.id IN (
    SELECT DISTINCT ON (U0."linkname", U0."left_uuid", U0."right_uuid") U0."id" AS Col1
    FROM "baseobj_link" U0
    WHERE U0."config_id" IN (2848)
    ORDER BY U0."linkname" ASC, U0."left_uuid" ASC, U0."right_uuid" ASC, U0."domain_level" ASC, U0."config_id" DESC, U0."is_deleted" DESC
)

ИзMYSQL документация по производным таблицам:

Производная таблица - это выражение, которое генерирует таблицу в рамках предложения FROM запроса.Например, подзапрос в предложении SELECT инструкции FROM является производной таблицей:

SELECT ... FROM (subquery) [AS] tbl_name ...

Дайте мне знать, как это работает.

...