Если в твоей команде ещё нет dbt — ты тратишь время впустую. Ad-hoc SQL-запросы, копипаста между дашбордами, необъяснимые расхождения цифр между отчётами — это всё лечится одним инструментом.
dbt (data build tool) — стандарт де-факто для трансформации данных в современных аналитических стеках. Этот гайд — про то что это, зачем тебе как аналитику и как написать первую модель за 30 минут.
Что такое dbt
Простыми словами: dbt позволяет писать SQL-модели как код. Каждая модель — это .sql файл с SELECT-запросом. dbt сам:
- Создаёт нужный
CREATE TABLEилиCREATE VIEWв БД - Управляет зависимостями между моделями (DAG)
- Запускает тесты
- Генерирует документацию
Это превращает SQL-аналитика в SQL-инженера без изучения Python/Spark.
Зачем аналитику dbt
До dbt
- 5 разных дашбордов считают одно и то же по-разному
- ad-hoc-запрос на 200 строк, без коммитов в git
- Никто не знает откуда берётся таблица
monthly_revenue_v2 - Цифры в отчёте за вторник ≠ цифры за пятницу за тот же период
После dbt
- ОДНА модель
monthly_revenue.sql— все дашборды берут оттуда - Версионирование через git — видно кто что менял
- DAG зависимостей — понятно от чего что берётся
- Автоматические тесты на nullable, unique, accepted values
Структура проекта dbt
my_project/
├── dbt_project.yml # main config
├── models/
│ ├── staging/ # очистка raw данных
│ │ ├── stg_users.sql
│ │ ├── stg_orders.sql
│ │ └── stg_events.sql
│ ├── intermediate/ # промежуточные модели
│ │ └── int_user_orders_joined.sql
│ └── marts/ # финальные витрины
│ ├── monthly_revenue.sql
│ └── retention_cohort.sql
├── tests/ # custom tests
├── macros/ # переиспользуемый Jinja-код
└── seeds/ # static CSV (страны, валюты)
Слой staging — копия raw с очисткой типов и переименованием. Слой marts — то что показываем в Tableau/PowerBI.
Первая модель за 5 минут
Шаг 1: установка
pip install dbt-postgres # или dbt-clickhouse, dbt-snowflake
dbt init my_project
cd my_project
Шаг 2: настройка подключения (~/.dbt/profiles.yml)
my_project:
target: dev
outputs:
dev:
type: postgres
host: localhost
user: analyst
password: secret
port: 5432
dbname: analytics
schema: dbt_dev
Шаг 3: первая модель
Создай models/staging/stg_orders.sql:
{{ config(materialized='view') }}
SELECT
id AS order_id,
user_id,
amount::numeric AS amount,
created_at::timestamp AS created_at,
DATE(created_at) AS order_date
FROM {{ source('raw', 'orders') }}
WHERE created_at >= '2024-01-01'
Шаг 4: запусти
dbt run --select stg_orders
dbt создаст VIEW dbt_dev.stg_orders в твоей БД на основе SELECT'а.
Materialization — главное что нужно знать
config(materialized='X') определяет КАК dbt создаст модель:
| Тип | Что создаёт | Когда использовать |
|---|---|---|
| view | CREATE VIEW | Лёгкие staging, всегда свежие данные |
| table | CREATE TABLE | Тяжёлые расчёты, читают часто |
| incremental | INSERT новые строки | Большие event-таблицы |
| ephemeral | CTE inline в зависимых моделях | Промежуточные шаги без storage |
{{ config(materialized='incremental', unique_key='event_id') }}
SELECT * FROM {{ source('raw', 'events') }}
{% if is_incremental() %}
WHERE event_ts > (SELECT MAX(event_ts) FROM {{ this }})
{% endif %}
При dbt run --full-refresh — пересчитает таблицу с нуля. При обычном run — только новые данные.
Зависимости через ref()
В моделях ссылайся на другие модели через {{ ref('model_name') }}:
-- models/marts/monthly_revenue.sql
SELECT
DATE_TRUNC('month', order_date) AS month,
SUM(amount) AS revenue,
COUNT(DISTINCT user_id) AS unique_buyers
FROM {{ ref('stg_orders') }}
GROUP BY DATE_TRUNC('month', order_date)
dbt автоматически:
- Поймёт что
monthly_revenueзависит отstg_orders - Запустит сначала
stg_orders, потомmonthly_revenue - Заменит
{{ ref('stg_orders') }}на полное имяdbt_dev.stg_orders
dbt run # запустит все модели в правильном порядке
dbt run --select monthly_revenue+ # эта и все зависимые
Тесты
Создай models/staging/_stg_orders.yml:
version: 2
models:
- name: stg_orders
columns:
- name: order_id
tests:
- unique
- not_null
- name: amount
tests:
- not_null
- name: user_id
tests:
- relationships:
to: ref('stg_users')
field: user_id
Запусти:
dbt test --select stg_orders
dbt сам сгенерит SQL-запросы которые проверяют unique/not_null/foreign keys, и упадёт с ошибкой если есть violations. Это уже production-grade data quality на минимуме усилий.
Документация
dbt docs generate # генерит метаданные
dbt docs serve # открывает локальный сайт http://localhost:8080
Получаешь автогенерированный сайт с:
- Описанием каждой модели
- DAG-визуализацией зависимостей
- Описанием колонок (если ты их добавил в YAML)
- Lineage — откуда что берётся
Реальные кейсы где dbt спасает
«Цифры расходятся между дашбордами»
Раньше: один Tableau считает MAU за последние 30 дней, другой — за календарный месяц. Спорят.
С dbt: одна модель mart_active_users, оба дашборда читают её. Источник истины ОДИН.
«Откуда взялась эта таблица?»
Раньше: коллега уволился, осталась таблица final_revenue_FINAL_2_v3. Никто не знает что в ней.
С dbt: каждая модель — git commit с автором, описанием, тестами.
«Изменили API → отвалились отчёты»
Раньше: продакт ничего не знал, заметил через неделю.
С dbt: тест relationships упал на nightly run, ты получил alert утром.
«Долго пересчитывается агрегат»
Раньше: каждое утро full re-aggregate 100M строк.
С dbt: materialized='incremental' — только новые данные. Агрегат обновляется за минуту, не за час.
Что НЕ нужно делать в dbt
- Хранить там credentials (используй env vars)
- Сложную бизнес-логику в Jinja (читаемость падает экспоненциально)
- Запускать тяжёлые ML-расчёты (это в Airflow / Spark)
- Хардкодить даты (используй
{{ var('start_date') }})
Roadmap для аналитика
| Срок | Что освоить |
|---|---|
| 1 неделя | Установка, первая модель, materializations |
| 2 неделя | ref(), source(), incremental, тесты |
| 1 месяц | macros, Jinja, документация, exposures |
| 2-3 месяца | dbt Cloud, dbt Power User для VS Code, dbt-utils |
| 6 месяцев | Архитектура staging/intermediate/marts на 50+ моделях |
Связанные материалы
- SQL-тренажёр — dbt это про SQL, тренируй базу
- ClickHouse для аналитика — частый бэкенд для dbt
- CTE в SQL — основа dbt-моделей
- Оконные функции SQL — нужны для marts-слоя
- Топ-50 вопросов на собеседование 2026 — на собесах в FAANG спрашивают про dbt
Установи dbt прямо сейчас (pip install dbt-postgres), напиши первую модель из 5 строк. Через час dbt будет твоим главным инструментом — серьёзно. После этого вернись в SQL-тренажёр и потренируй CTE — это core dbt-моделей.