Предварительная фильтрация данных во вложенном запросе по значениям фильтров в Apache Superset
Вопрос оптимизации запросов для виртуальных датасетов Apache Superset является достаточно актуальным, так как это в большой степени влияет на скорость визуализации данных отчета. С точки зрения пользователя дашборда это критичный показатель. В некоторых случаях перенос логики расчета в ХД невозможен, поэтому необходимо добавлять предварительную фильтрацию данных в виртуальный датасет.
Для визуализации используются выборки данных из исходного набора, по значениям фильтров, это значит, что менять датасет необходимо динамически. В этом нам помогут шаблоны Jinja. В стандартном пакете установки они выключены, чтобы их включить нужно установить ENABLE_TEMPLATE_PROCESSING флаг функции в superset_config.py. После этого можно встраивать код Python в виртуальные наборы данных.
1. Создадим тестовый запрос, чарт с таблицей, справочник для фильтра и сам фильтр:
Запрос для таблицы
select 'col1_param1' as column, 1 as value union all select 'col1_param1' as column, 2 as value union all select 'col1_param2' as column, 3 as value union all select 'col1_param1' as column, 1 as value union all select 'col1_param1' as column, 2 as value union all select 'col1_param2' as column, 3 as value Запрос для справочника фильтра select 'col1_param1' as column_for_filter union all select 'col1_param2' as column_for_filter
Вид чарта и фильтра в дашборде
В таком виде фильтр работать не будет, так как колонки в датасете и таблице имеют разные имена.
Если посмотреть на итоговый запрос (нажать на свойства чарта => View query), то фильтрация в исходной конфигурации будет вставляться в позицию 1, нам необходимо вставить фильтр в позицию 2.
SELECT "column" AS "column", value AS value FROM (select 'col1_param1' as column, 1 as value union all select 'col1_param1' as column, 2 as value union all select 'col1_param2' as column, 3 as value union all select 'col1_param1' as column, 1 as value union all select 'col1_param1' as column, 2 as value union all select 'col1_param2' as column, 3 as value where <Позиция 2>) AS virtual_table WHERE <Позиция 1> LIMIT 1000;
2. Отредактируем запрос для виртуального датасета.
В шаблонах Jinja есть функция filter_values(), которая возвращает массив выбранных значений фильтров. Чтобы функция заработала в запросе ее нужно заключить в двойные фигурные скобки и в качестве аргумента передать название колонки, которое было использовано в фильтре. Ограничимся одним значением для фильтрации, так как на выходе будет массив, укажем первый его элемент. Шаблон для фильтрации будет выглядеть следующим образом:
{{ filter_values('column_for_filter',)[0] }}, вставим его в исходный датасет.
select column, value
from
(select 'col1_param1' as column, 1 as value
union all select 'col1_param1' as column, 2 as value
union all select 'col1_param2' as column, 3 as value
union all select 'col1_param1' as column, 1 as value
union all select 'col1_param1' as column, 2 as value
union all select 'col1_param2' as column, 3 as value) as t
where column in ('{{ filter_values('column_for_filter',)[0] }}')
Итоговый результат
Со всеми возможностями использования шаблонов Jinja можно ознакомиться в документации SuperSet по ссылке:
https://superset.apache.org/docs/installation/sql-templating/
Источник: Блог bilab




