Из общего обзора — в конкретные детали одним кликом (Deep-linking фильтров как альтернатива Drill-Through в Microsoft Power BI, Tableau и Qlik).
За один клик из сводного дашборда — на «дочерний» с уже выставленными фильтрами. Разберём, как в Superset прокидывать выбранные значения через URL-параметр native_filters в формате Rison и собирать ссылку Jinja-макросами.

Каждый, кто работал с дашбордами, знает эту боль: смотришь на сводный отчёт, находишь интересный сегмент — и дальше приходится вручную проставлять те же фильтры в отдельном дашборде с детализацией. В Superset можно обойтись без этого рутинного «прокликивания»: достаточно один раз настроить deep-linking с помощью формата Rison и шаблонов Jinja. Тогда переход в дочерний дашборд будет происходить уже с выбранным контекстом (страна, клиент, продукт, временной период и т. д.). Такой deep-linking заметно ускоряет аналитику и делает работу с данными гораздо удобнее. По сути, это аналог Drill-Through, давно ставшего стандартом в коммерческих BI-системах — лидерах рынка — Microsoft Power BI, Tableau и Qlik , хотя в Superset требуется больше усилий для его настройки.
На этом коротком видео показан некий родительский дашборд (cars_rison_dash(parent)) , на котором можно выбрать значения различных фильтров (в том числе кросс-фильтров) и после клика на кнопку «Перейти в детализированный дашборд» происходит переход в более детализированный дочерний дашборд (cars_rison_dash(child)) с пробросом значений фильтров из родительского дашборда.
Далее в статье на примере этих двух дашбордов рассмотрим как все это работает на практике с небольшими отступлениями в теорию.
Тот, кто захочет повторить может скачать себе датасет cars отсюда: https://anonymfile.com/BXZKQ/cars.rar (на нем для простоты построены все чарты обоих дашбордов).
Итак, немного теории.
Что такое rison-формат и для чего он используется в Superset
Rison — это компактный формат сериализации данных, который похож на JSON, но гораздо более удобен для использования в URL.
Достаточно посмотреть на следующие примеры, чтобы понять основы Rison.
В JSON массив выглядит так:
[«Canada», «China»]
В Rison то же самое запишется компактно:
!('Canada','China')
Объект в JSON:
{
«name»: «Lacazette»,
«age»: 27,
«stats»: {
«appearances»: 20,
«goals»: 7,
«assists»: 5
}
}
В Rison:
(name:Lacazette,age:27,stats:(appearances:20,goals:7,assists:5))
В Rison скобки (...) обозначают объект , который в JSON указывается в фигурных скобках {…}, а восклицательный знак с круглыми скобками !(...) в Rison обозначает массив, который в JSON указывается в квадратных скобках […].
Строки можно писать без кавычек, если они не содержат пробелов или специальных символов вроде :, ().
Главное удобство Rison в том, что такие строки можно без проблем вставлять в URL как параметры запроса — без дополнительного кодирования. Конечно, если внутри окажутся «опасные» символы, их придётся закодировать. Но сама спецификация Rison специально придумана так, чтобы свести к минимуму необходимость кодирования. Более того, некоторые символы, которые в обычных URL пришлось бы экранировать, в Rison остаются «чистыми» и читаемыми.
Для примера рассмотрим один и тот же упрощенный адрес страницы с параметром в Rison в сравнении с этим же адресом страницы со стандартным URI (Uniform Resource Identifier)-кодированием пробелов, кавычек, запятых и проч.
Чистая Rison-строка в адресе страницы:
http://localhost:8089/superset/dashboard/67/?native_filters=(country:!('Canada','China'),year:2024)
Эта строка удобно читается и видно, что в параметре native_filters прописано , что фильтруется country по двум значениям 'Canada','China' , а год year=2024.
Та же самая строка с URI-кодированием в адресе страницы:
http://localhost:8089/superset/dashboard/67/?native_filters=%28country%3A%21%28%27Canada%27%2C%27China%27%29%2Cyear%3A2024%29
Здесь:
( превратился в %28,
: в %3A,
! в %21,
, в %2C,
' в %27,
) в %29.
Как видно, закодированный вариант громоздкий и плохо читается. Поэтому Rison и ценен: он подобран так, чтобы по максимуму избежать лишнего кодирования и оставить URL компактным и понятным не только машине, но и человеку.
Теперь рассмотрим для чего Rison используется в Superset.
В Apache Superset этот формат в контексте нашей задачи используется для передачи состояния фильтров через URL. Ключевой параметр здесь — native_filters:
в нём закодирован выбранный пользователем контекст (например, страна, продукт, временной диапазон и другие фильтры дашборда);
Rison позволяет уместить всю структуру в одну строку без «раздувания» URL.
Иными словами: вы вставляете Rison-строку в параметр native_filters, браузер передаёт её как текст, а Superset на стороне фронтенда «знает», что в native_filters лежит именно Rison, и умеет её правильно распарсить и далее применять все переданные параметры фильтров для дашборда.
Благодаря этому можно формировать deep-links: ссылки, которые открывают дочерний дашборд с уже предустановленными фильтрами.
Подытоживая теоретическую часть по Rison, стоит отметить, что существуют библиотеки- парсеры Rison для языков программирования: JavaScript, Python, Golang и др.
Сравнение синтаксисов Rison vs JSON представлено в таблице ниже.


Страница на гитхаб с подробным описанием формата https://github.com/Nanonid/rison
Что такое Jinja Template и для чего это используется в Apache Superset.
Второй и заключительный теоретический блок касается механизма прокидывания значений фильтров дашборда в SQL – запрос.
В Apache Superset для этого используется популярный шаблонизатор на Python Jinja. Он позволяет динамически подставлять значения фильтров дашборда прямо в SQL датасета. Благодаря этому один и тот же SQL -запрос становится «живым» — он адаптируется под выбор пользователя на фильтрах дашборда.
По сути, Jinja в Superset — это слой между интерфейсом дашборда и SQL:
пользователь кликает фильтр;
выбранные значения через макросы Jinja (filter_values, get_filters, from_dttm, to_dttm и другие) попадают в SQL;
Далее в контексте нашей задачи SQL генерирует результат или строку с параметрами для Rison, которая затем используется в deep-linking.
Актуальная документация по SQL-шаблонизации Jinja доступна на официальном сайте Superset:
? https://superset.apache.org/docs/configuration/sql-templating/
Хорошие разборы и практические примеры можно найти здесь:
? https://preset.io/blog/intro-jinja-templating-apache-superset/
Синтаксис Jinja минималистичный:
{{ ... }} — вывод переменной или выражения;
{% ... %} — управляющие конструкции (условия, циклы, переменные);
{# ... #} — комментарии.
В целях нашей задачи мы будем использовать следующие встроенные в Superset макросы Jinja
1) filter_values(name) → list : [‘value1’ ,… , ’valueN’].
Что делает: возвращает питоновский список выбранных значений нативного фильтра дашборда типа Value. Параметр name внутри макроса filter_values – это имя колонки датасета, по которой сделан фильтр.
Когда использовать: когда нужно подставить значения IN (...) или собрать массив для Rison.
2) get_filters(name) → list[dict]
Что делает: возвращает список условий по фильтру со следующими деталями: оператор (op) и значение (val). Подходит для сложных случаев: диапазонные фильтры типа Numerical Range. Параметр name внутри макроса get_filters – это имя колонки датасета, по которой сделан фильтр.
Зачем: можно гибко разобрать, какая именно грань/оператор выбран на Numerical Range -фильтре, и собрать корректный Rison-узел или SQL-условие.
3) from_dttm / to_dttm → str (строки дат)
Что делает: предоставляют нижнюю/верхнюю границы выбранного пользователем временного диапазона (фильтр типа Time Range) в формате, готовом к подстановке в SQL.
4) time_grain → str (ISO-8601 длительность)
Что делает: содержит выбранный time grain (агрегационный шаг времени), например P1D (день), P1W (неделя), P1M (месяц), PT1H (час) и т. д.
Зачем: можно отобразить человекочитаемую подпись или передать time_grain ниже по конвейеру (например, в extraFormData Rison).
5) Вспомогательное: namespace(...) (Jinja-фича)
Что делает: создаёт мутабельный контейнер для накопления значений внутри цикла.
Зачем: Jinja по умолчанию не даёт «вынести» значения из цикла простым set; namespace помогает аккуратно собирать состояние.
Ну, довольно теории — пора перейти к рассмотрению практического примера.
Формулировка потребностей практического кейса:
мы хотим перейти из одного дашборда к другому дашборду с уже установленными фильтрами;
мы хотим поделиться своим дашбордом с кем-то с сохраненными фильтрами.
Вариант реализации в Superset от 3й версии и выше (все скрипты в этом кейсе протестированы и реализованы в версиях 4 и 5)
Допустим, у нас есть несколько нативных фильтров и мы хотим прокинуть выбранные значения в параметры ссылки на дашборд, чтобы при переходе по этой ссылке открывался сразу отфильтрованный дашборд.
Для фильтрации нам нужно подставить параметр native_filters в URL- дочернего дашборда следующим образом:
(подробное описание механизма тут : https://www.blef.fr/superset-filters-in-url/ ):

Тогда произойдёт перенаправление на страницу дочернего дашборда с параметром native_filters_key в URL. Это означает, что выбранные вами в родительском дашборде фильтры были сохранены в таблице метаданных key_value.
Структура Rison-параметра native_filters
Когда мы прокидываем состояние фильтров через URL, Superset кодирует их в параметре native_filters=(...). Внутри каждого блока встречаются одинаковые ключи, отвечающие за разные части состояния.
__cache (в нашем кейсе мы не будем использовать этот ключ)
Внутренний кэш состояния фильтра. Содержит «человекочитаемую» подпись (label) и текущее значение (value). Superset использует это, чтобы быстрее восстановить интерфейс фильтра при открытии дашборда.
extraFormData
Технический блок, где описывается, какое условие реально применять в SQL.
filters → список словарей вида (col:, op:<оператор>, val:<значения>).
Именно отсюда Superset понимает, какую колонку фильтровать, каким оператором и какими значениями.
filterState
Главный блок состояния фильтра. Содержит:
label — подпись для отображения в UI (обычно совпадает с выбранным значением или их списком),
value — собственно выбранные значения,
validateStatus — служебный флаг проверки корректности состояния (!f = false, то есть валидация отключена).
ownState — зарезервированная часть для локальных состояний и расширений. Обычно остаётся пустой (), но Superset оставляет её для будущих фич (например, сложных композитных фильтров).
Ключевые элементы внутри блоков
<id>
— уникальный идентификатор фильтра на дашборде (NATIVE_FILTER-...). Генерируется Superset автоматически. Используется для связи Rison-записи с конкретным фильтром.
Вы можете получить NATIVE_FILTER-<id>
, в свойствах дочернего дашборда или в консоли разработчика веб-браузера (описано ниже)

-
<column>
— имя колонки в источнике данных (датасете), к которой будет применяться фильтр. Важно: это имя колонки, а не название фильтра в UI. (Чтобы избежать путаницы можно задавать название фильтра в UI в панели фильтров , такое же как и имя колонки, по которой этот фильтр создан)
validateStatus — статус валидации. Если !f (false), Superset не проверяет дополнительно выбранное состояние.
val или
<value>
— список выбранных значений фильтра. В Rison-массиве это выглядит как!('Canada','China')
.op — оператор сравнения (IN, =, >=, <=, IS NULL, BETWEEN и др.). Определяет логику фильтрации.
В результате Superset получает полное описание фильтра: и то, что нужно отобразить пользователю в интерфейсе (__cache, filterState), и то, что нужно реально применить к данным в SQL (extraFormData).
Вот как выглядит ссылка в формате RISON с учетом выбранных в родительском дашборде в панели фильтров значений.

На скрине цвет прямоугольника вокруг фильтра, совпадает с цветом выделения текста в Rison-ссылке ниже , где указаны параметры фильтра.

Где еще можно посмотреть id-фильтров и ключ/значения , которые Superset использует для передачи состояния фильтров дашборда?
В консоли разработчика вашего веб-браузера.
Зайдите в консоль разработчика веб-браузера, выставьте нужные значения фильтров в панели фильтров детского (!) дашборда и нажмите Apply filters. В консоли разработчика найдите вкладку Network и среди прочих запросов найдите запрос , который начинается на filter_state и во вкладке payload этого запроса можно увидеть json , который описывает состояние фильтров дашборда (id -фильтров, названия колонок и выбранные значения). Этот json тоже можно использовать как образец для формирования ссылки в формате rison.

Итак, мы получили валидную ссылку в формате RISON.
Как использовать сформированный URL ?
Для того , чтобы сформированная вами ссылка в формате RISON стала кликабельной на дашборде её необходимо обернуть в HTML-тэг
<a href="ваша ссылка в формате RISON"> текст ссылки </a>
Пример таблицы с кликабельной ссылкой может выглядеть так:
SELECT *, '<a href="' "ваша ссылка в формате RISON" '">' 'имя ссылки , которое будет видно пользователю на дашборде' '</a>' as link
Идем дальше.
Создаем два дашборда:
родительский дашборд , то есть тот дашборд, от которого мы будем прокидывать фильтры в детский дашборд.
Например такой:

детский дашборд , то есть тот дашборд , на который мы будем прокидывать фильтры с родительского дашборда.
Например такой:

Фильтры в обоих дашбордах одинаковые.
В данном примере мы будем работать со всеми пятью типами фильтров , которые возможно установить на дашборде в Superset.
На дашбордах установлены следующие фильтры:
-
фильтр типа Numerical range по столбцу amount_pct
-
2 фильтра типа Value по столбцам country и car
-
фильтр типа Time range, в котором выбирается период дат для фильтрации столбца с датой.
-
фильтр типа Time grain, в котором выбирается гранулярность (день, месяц, год, квартал и т. д..) для группировки столбца с датой.
-
фильтр типа Time column*, в котором выбирается один из двух столбцов с датой, к которому будет применяться фильтрация и группировка по датам . В нашем датасете есть два столбца с датами: date и date_of_shipment
*фильтр Time column родительского дашборда сделан на вспомогательном датасете под названием rison_time_column с одной колонкой time_column_rison и двумя строками со значениями date и date_of_shipment и имеет тип Value , так как в версии Superset 5.0 макрос jinja time_column не всегда работает как ожидается и поэтому для получения значения фильтра time_column в родительском дашборде используется макрос filter_values.

-
Скрипт датасета rison_time_column на основе которого создан фильтра time_column в родительском дашборде:
Значения выбранные в фильтрах родительского дашборда будут проброшены в параметры URL дочернего дашборда в RISON-формате и таким образом мы получим ссылку на дочерний дашборд с сохранением всех выбранных на родительском дашборде фильтров.
Ниже краткий обзор родительского и дочернего дашбордов.
На скрине представлен родительский дашборд, в котором на панели фильтров выбраны
некоторые значения для всех возможных типов фильтров ( Values, Numerical range, Time column, Time grain, Time range) .
Эти выбранные в фильтрах значения проброшены параметрами в ссылку URL в формате RISON, ведущую на дочерний дашборд.

Дочерний дашборд при переходе по параметризованной ссылке из родительского дашборда наследует все значения всех фильтров , установленных на родительском дашборде (здесь мы принимаем во внимание , что на дочернем дашборде в панели фильтров установлены точно такие же фильтры, как на родительском дашборде).

Приступаем к завершительной части.
Конструктор чарта родительского дашборда , который содержит нашу ссылку в формате rison выглядит так:

Датасет лежащий в основе этого чарта имеет название rison_test и следующий код:
|
В коде представленном выше формируется таблица, в которой в столбце link_plain формируется ссылка на дочерний дашборд в формате RISON и кликабельная ссылка '<a href="' link_plain '" target="_blank">link</a>'
в столбце link.
На этом всё.
Спасибо, что дочитали до конца! Надеюсь, статья будет полезной.