Lightdash — BI, который живёт внутри вашего dbt‑проекта

от автора

Метрики как код: бизнес‑логика в dbt вместо настроек BI

В начале немного контекста. Я — аналитик данных в команде BIGDATAHOUSE, и на всех проектах трансформацию данных реализую через dbt — де‑факто стандарт, в качестве BI в основном использую Superset. Бизнес‑логика в таком стеке оказывается разбита по двум местам: одна её часть оседает в dbt, другая описывается в BI. Со временем эти две части неизбежно расходятся, и отследить такие расхождения становится всё сложнее. Из профессионального интереса изучая альтернативные BI‑платформы, я наткнулся на Lightdash. Он обещает закрыть эту и ряд других проблем.

Теперь представьте ситуацию (возможно некоторым и представлять не нужно, достаточно вспомнить рабочие будни): на созвоне кто‑то задаёт вопрос «а какая у нас выручка за квартал?», и в этот момент одновременно озвучивают три разных цифры. Одна из дашборда в Superset, вторая из выгрузки CSV файла, а третья из SQL запроса к базе данных. И дальше команда обсуждает не бизнес задачу, а то, какая цифра является корректной. Но проблема может быть даже не в ошибке расчётов, а в том, что каждый держит в голове своё определение выручки.

Эту неоднозначность закрывают инструменты семантического слоя: метрика описывается один раз в коде (об этом чуть позже), и везде — от ad‑hoc запросов до дашбордов — используется одно и то же определение.

Одним из таких инструментов и является Lightdash — BI‑платформа с открытым исходным кодом, предоставляющая возможность нетехническим пользователям самостоятельно исследовать показатели, строить визуализации и дашборды (ведь метрики и измерения описывают аналитики и дата‑инженеры, а дальше в BI работают уже все желающие, например, менеджеры или руководители).

Главная особенность Lightdash как раз в том, что он изначально строится вокруг dbt и семантического слоя. Вместо того чтобы реализовывать ещё один слой моделирования в BI‑инструменте, Lightdash берёт dbt‑модели и YAML‑определения метрик как единственный источник истины. Метрики и модели версионируются, любые изменения проходят ревью, их можно легко откатить, покрыть тестами. Благодаря этому Lightdash наследует все ключевые преимущества dbt и переносит их в пласт BI.

Таким образом, платформа ощущается как естественное продолжение современного дата‑стэка, а не обособленная система, где данные нужно проектировать заново.

От вопроса до чарта за несколько кликов

Начну не с теории, а с демонстрации простого сценария: допустим, перед вами стоит задача узнать, сколько было клиентов и какой объём денежных средств они принесли за определённый период времени.

При иных обстоятельствах приходится обращаться к аналитикам и ожидать их ответа в виде графика или выгрузки в другом формате. В Lightdash это происходит следующим образом: вы открываете список таблиц (на самом деле это dbt‑модели с описанием метаданных в формате YAML), выбираете необходимую для исследования и попадаете в раздел «Explore» — слева панель с готовыми измерениями и метриками, справа — пустой холст. Не нужно писать ни строчки SQL‑кода, визуализация строится по принципу drag‑and‑drop, далее настраиваете фильтры, внешний вид графика (кастомизация, кстати, в Lightdash держит достойный уровень и заслуживает отдельного обзора разнообразия визуализаций в целом и их «продвинутых» настроек) и получаете ответ на бизнес‑вопрос, а если запросов несколько — чарты собираются в дашборд.

Анатомия YAML‑файла

models:  - name: customers    config:      meta:        primary_key: customer_id        joins:          - join: orders            sql_on: ${customers.customer_id} = ${orders.customer_id}            relationship: one-to-many      - join: payments            sql_on: ${orders.order_id} = ${payments.order_id}            relationship: one-to-many    columns:      - name: customer_id        description: This is a unique identifier for a customer        tests:          - unique          - not_null        config:          meta:            dimension: type: number            metrics:              unique_customer_count:                tags: ["period_metric"]                type: count_distinct                label: Unique customer count                description: Total number of customers                spotlight:                  categories: ["core", "revenue_growth"]              total_order_amount_deduped:                type: sum_distinct                sql: ${orders.amount}                distinct_keys: [orders.order_id]                format: usd                round: 2      - name: created        description: Timestamp (UTC) when customer was created        config:          meta:            dimension:              type: timestamp            metrics:              date_of_first_created_customer:                type: min              date_of_most_recent_created_customer:                type: max

Буквально пара слов про сам dbt — это инструмент трансформации данных в хранилище: вы пишете SQL‑запросы (модели), а dbt сам понимает порядок их выполнения, материализует результаты, тестирует и генерирует документацию. С SQL‑моделями сосуществуют YAML‑файлы с метаданными.

Прежде чем разбирать, почему график собрался за пару кликов, стоит понять одну неочевидную вещь про файл выше — это файл из dbt‑проекта, но не весь он «про dbt».

dbt из этого YAML знает не все инструкции: models, name, description, columns, tests (unique, not_null), config — это стандартные свойства модели, которые dbt читает, валидирует и использует для генерации документации и тестов. А вот всё, что лежит внутри конфига meta — dimension, metrics, joins — dbt не интерпретирует вообще. Для него meta — это произвольный словарь, который он пробрасывает дальше, не заглядывая внутрь.

Именно здесь и появляется Lightdash. Он читает тот же файл, но смотрит в meta и достаёт оттуда свою семантику: метрики, измерения и связи, YAML остаётся полностью валидным dbt‑файлом, проект собирается и тестируется как обычно, а BI‑логика живёт рядом, ничего не нарушая.

Обратите внимание на блок joins в конфиге — там ответ на вопрос «почему простой drag‑and‑drop корректно обрабатывает композитные метрики». Заметьте две инструкции, обе снимают с конечного пользователя работу, которую иначе пришлось бы реализовывать на SQL:

  • sql_on — условие соединения (ON из JOIN). Заполняется один раз и в дальнейшем любые чарты, где потребуется соединение таблицы customers с orders или payments будут объединены именно по этому правилу;

  • relationships определяет мощность связи, например, связь customersorders обозначена как one‑to‑many, то есть одному клиенту соответствует много заказов.

И тут стоит заметить, что метрика total_order_amount_deduped с distinct_keys нужна именно потому, что связь customersorderspayments множит строки, но теперь Lightdash об этом осведомлён и считает сумму корректно.

Коротко о блоке metrics:

  • unique_customer_count — count_distinct по customer_id = кол‑ву уникальных клиентов;

  • total_order_amount_deduped — sum_distinct с distinct_keys = дедуплицированной сумме заказов.

Т.е. левая панель в UI содержит не сырые колонки, а готовые агрегации с предопределёнными типами. Вы выбираете «что» посчитать, а «как» — определено в YAML файлах.

Измерения — это то, по каким атрибутам вы группируете. Описали колонку в YAML (в примере выше — created — дата создания пользователя), и она доступна в BI, с соответствующим типом данных, от которого зависят доступные фильтры.

Чем ещё выделяется Lightdash?

Drill‑down до сырых записей

В Lightdash любой агрегат можно проверить, к примеру, чтобы понять, откуда на графике резкий выброс значений. Для этого достаточно кликнуть по элементу визуализации (столбцу, точке, ячейке таблицы) и выбрать «View underlying data» — на скриншотах ниже это показано на конкретном примере: круговая диаграмма с распределением суммы заказов по странам, кликаем по US. Видно меню и открывшуюся следом таблицу сырых строк, собранную с учётом тех же фильтров и группировок, что и на графике.

Table Calculation

Основные метрики живут в YAML и они могут быть сколь угодно сложными. Но заводить новый показатель в коде ради одной цифры в отчёте или проверки гипотезы может быть избыточно.

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

Наглядный пример — средний чек в разрезе стран. В чарте по country_orders уже выбраны total_order_amount и order_count, и этого достаточно: добавляете table calculation @{total_order_amount} / @{order_count} — и рядом с суммой и количеством заказов появляется новая колонка со средним чеком по каждой стране.

Версионирование чартов

Lightdash хранит историю версий каждого чарта: можно посмотреть, что и когда менялось, и откатиться к любой предыдущей версии — отличная страховка для командной работы.

RLS и CLS с помощью пользовательских атрибутов

Доступ в Lightdash можно ограничивать не только на уровне проекта, но и на уровне отдельных полей и метрик. В YAML для этого прописывается условие доступа — блок required_attributes. Например, так чувствительное поле скрывается от всех, кроме администраторов:

columns:  - name: age    meta:      dimension:        required_attributes:          is_admin: "true"

Пользователь без указанного значения (is_admin: "true") это поле просто не увидит — вместе со всеми метриками, которые от него зависят. Если условий несколько, required_attributes работает по логике ‘И’, а конструкция any_attributes — по логике ‘ИЛИ’.

Сами пользовательские атрибуты (user attributes) при этом создаёт админ через интерфейс и назначает значения конкретным пользователям или группам. В YAML вы лишь ссылаетесь на нужное условие — кому и какое значение присвоено, решается в UI.

А если ограничивать нужно не колонки, а строки, есть конструкция sql_filter, которая добавляет условие прямо в WHERE запроса к хранилищу.

Получается row/column‑level security, описанная в коде, рядом с самими данными.

Развитый Developer Experience

Lightdash умеет поднимать превью проекты и валидировать контент через CI/CD, и для команды разработки это удобный паттерн, заметно отличающий Lightdash от других BI‑инструментов.

Превью проект — это временная копия продакшн проекта: чарты и дашборды копируются из продакшна и можно безопасно экспериментировать с метриками, измерениями и контентом. Настроив GitHub Actions, вы получаете такой проект автоматически на каждый пулл‑реквест, при каждом новом коммите превью обновляется, а после мержа или закрытия PR удаляется.

Теперь про валидацию контента: команда lightdash validate проверяет, не нарушают ли внесённые изменения существующие чарты и дашборды. В CI процессе эту команду используют как триггер перед принятием изменений: при обнаружении ошибок правки не попадут в основную ветку, пока проверка не завершится успешно. Результат валидации доступен и в интерфейсе: в настройках проекта есть вкладка «Validator» со списком повреждённых чартов и дашбордов и причинами ошибок. Стоит учитывать ограничение: валидатор проверяет ссылки и определения метрик и измерений, но не исполняемый SQL, поэтому ошибку в синтаксисе запроса он не обнаружит.

Помимо этого, Lightdash делает контент управляемым через код наравне с моделями: чарты и дашборды выгружаются в YAML, правятся и загружаются обратно через командную строку — в результате визуализации версионируются и проходят ревью так же, как dbt‑модели. dbt write‑back работает в обратную сторону: новое измерение создаётся прямо в интерфейсе Lightdash, а его YAML‑описание отправляется запросом на слияние в репозиторий dbt.

Заключение

В этой части я постарался показать Lightdash с двух сторон. Сначала — как идею: бизнес‑логика живёт в dbt, а BI лишь читает её из YAML, не заводя собственного слоя моделирования. Затем — как инструмент: разобрал устройство YAML‑файла, drill‑down до сырых строк, вычисляемые поля, версионирование чартов, управление доступом через пользовательские атрибуты, а также превью‑проекты и валидацию контента.

Уместить всё в одну статью не получилось бы: только библиотека визуализаций и их настройки тянут на отдельный разбор. Поэтому материал выходит порционно.

Во второй части я планирую:

  • собрать полноценный дашборд и разобрать его фильтры и оформление;

  • пройтись по библиотеке визуализаций и их кастомизации, включая кастомные чарты на Vega‑Lite;

  • объективно разобрать недостатки;

  • сравнить облачную версию и self‑hosted;

  • подвести итог: кому инструмент подойдёт, а кому разумнее остаться на привычном стеке.

А пока можно самостоятельно пощупать Lightdash: есть публичное демо, где без установки и собственного dbt‑проекта доступны примеры визуализаций и запросов. Полноценного опыта «метрик как кода» оно не даст, но для первого знакомства этого достаточно.

ссылка на оригинал статьи https://habr.com/ru/articles/1067570/