Что такое dbt и как он преобразует данные в хранилище
Основы4 минРедакция Innovialabs
Коротко
dbt — это инструмент, который выполняет трансформации данных прямо в хранилище: вы пишете модели как обычные SELECT-запросы, а dbt строит их в правильном порядке, тестирует и документирует.
Коротко: что делает dbt
dbt (data build tool) отвечает за букву T в схеме ELT: Extract, Load, Transform. Данные сначала загружаются в хранилище как есть (из CRM, базы приложения, платёжных систем), а потом dbt превращает их в чистые таблицы для отчётов.
dbt не забирает данные из источников и не хранит их сам. Он:
- берёт ваши SQL-модели — файлы с одним
SELECT; - превращает их в таблицы или представления в хранилище (PostgreSQL, BigQuery, Snowflake, ClickHouse и другие через адаптеры);
- сам определяет порядок построения по зависимостям между моделями;
- прогоняет тесты на качество данных;
- генерирует документацию и граф происхождения данных (lineage).
По сути, dbt приносит в аналитический SQL практики разработки: Git, код-ревью, тесты, окружения dev и prod.
Модели и ref()
Модель — это файл .sql в папке models/. Имя файла становится именем таблицы или view. Вместо жёстко прописанных имён таблиц модели ссылаются друг на друга через ref():
-- models/marts/fct_orders.sql
select
o.order_id,
o.customer_id,
o.created_at::date as order_date,
sum(i.price * i.quantity) as order_total
from {{ ref('stg_orders') }} o
join {{ ref('stg_order_items') }} i on i.order_id = o.order_id
group by 1, 2, 3
ref() решает две задачи: подставляет правильную схему для текущего окружения и сообщает dbt, что fct_orders зависит от двух staging-моделей. Из этих связей строится граф (DAG), и dbt run выполняет модели в нужном порядке.
Сырые таблицы, которые загрузил внешний инструмент, объявляются как sources и вызываются через source('shop', 'orders').
Слои: staging и marts
Типичная структура проекта:
| Слой | Что внутри | Пример |
|---|---|---|
| staging | Одна модель на одну сырую таблицу: переименование колонок, приведение типов, чистка | stg_orders, stg_payments |
| intermediate (по желанию) | Промежуточные объединения и расчёты | int_orders_with_payments |
| marts | Готовые таблицы для бизнеса: факты и измерения | fct_orders, dim_customers |
Правило простое: marts читают только из staging или intermediate, а не из сырых таблиц напрямую. Тогда при смене источника вы правите одну staging-модель, а не десяток отчётов.
Тесты и документация
Тесты описываются в YAML рядом с моделями:
# models/staging/stg_orders.yml
version: 2
models:
- name: stg_orders
description: "Заказы из базы интернет-магазина, по одной строке на заказ"
columns:
- name: order_id
tests: [unique, not_null]
- name: status
tests:
- accepted_values:
values: ['new', 'paid', 'shipped', 'cancelled']
Встроенные тесты: unique, not_null, accepted_values, relationships. Можно писать и свои — SQL-запрос, который должен вернуть ноль строк. Команда dbt build строит модели и сразу их тестирует.
dbt docs generate собирает описания, колонки и граф lineage в сайт с документацией. Видно, из каких источников собирается каждая метрика и что сломается, если изменить таблицу.
Минимальный проект
my_project/
dbt_project.yml
models/
staging/
sources.yml
stg_orders.sql
stg_orders.yml
marts/
fct_orders.sql
Подключение к хранилищу задаётся в profiles.yml. Дальше рабочий цикл: изменить модель, запустить dbt build --select fct_orders+ (модель и всё, что от неё зависит), проверить, закоммитить.
Модели можно материализовать по-разному: view, table, incremental (дописывать только новые строки) и ephemeral (подставляется в другие модели как CTE).
Когда маленькой команде нужен dbt
Нужен, если:
- у вас уже есть хранилище, и в него регулярно загружаются данные из нескольких источников;
- SQL-логика отчётов разрослась, и разные дашборды считают одну метрику по-разному;
- над аналитикой работают хотя бы два человека, и нужна история изменений;
- были случаи, когда отчёт «тихо» ломался после изменения в источнике.
Пока рано, если:
- данные из одного источника, а отчётов несколько штук;
- аналитика живёт во встроенных отчётах CRM или BI-инструмента и всех устраивает;
- хранилища нет — сначала нужно решить загрузку данных.
Частые ошибки
- Писать marts напрямую поверх сырых таблиц, пропуская staging.
- Обходиться без тестов на ключевых колонках — именно они ловят дубли после JOIN.
- Делать все модели
tableс первого дня: view дешевле, пока объём небольшой. - Хранить бизнес-логику одновременно в dbt и в BI-инструменте.