Проблема, которую решает dbt
Что было больно до dbt и какие именно практики он принёс в мир SQL-трансформаций.
SQL-хаос — состояние, когда логика трансформаций размазана по сотням несвязанных запросов без тестов, версий и документации, и никто не знает полной картины.
Как выглядела жизнь до dbt
Представьте компанию, где десять аналитиков пишут SQL. У каждого свой набор «сохранённых запросов» в редакторе. Метрика «выручка» считается в дашборде маркетинга одним способом, в отчёте финансов — другим, в выгрузке для совета директоров — третьим. Когда генеральный спрашивает «сколько мы заработали?», три отдела называют три разные цифры — и все формально правы, потому что определения разошлись.
Запросы запускались вручную или через хрупкие cron-скрипты. Если запрос B читал таблицу, которую создаёт запрос A, кто-то должен был помнить запустить A раньше B. Забыл — получил вчерашние данные или ошибку. Никто не тестировал результат: первичный ключ внезапно задвоился, и это всплывало через неделю в отчёте, когда уже поздно.
Четыре боли и четыре ответа dbt
| Боль | Что давал «голый SQL» | Что даёт dbt |
| Нет версионирования | Запрос живёт в голове или в чате | Каждая модель — файл в git, история изменений, ревью |
| Нет тестов | Ошибку находит бизнес в отчёте | Тесты данных (unique, not_null, отношения) в коде |
| Нет документации | «Спроси у Васи, он писал» | Авто-документация и граф зависимостей |
| Нет порядка запуска | Помни сам или пиши cron | DAG строится автоматически по ref() |
Как работает под капотом
Идея dbt обманчиво проста: вы по-прежнему пишете обычный SELECT, но dbt оборачивает его в инженерную обвязку. Из файла-модели dbt сам строит команду CREATE TABLE AS или CREATE VIEW AS, определяет порядок запуска по ссылкам между моделями, прогоняет тесты и собирает документацию. Вы пишете что посчитать, dbt берёт на себя как это выполнить надёжно.
-- Демонстрация SQL-хаоса: две версии "активного клиента"
CREATE TABLE orders (id INTEGER, customer_id INTEGER, days_since INTEGER);
INSERT INTO orders VALUES (1, 10, 5), (2, 10, 40), (3, 20, 80);
-- Отдел A: активный = заказ за 30 дней
SELECT DISTINCT customer_id FROM orders WHERE days_since <= 30;
-- Отдел B: активный = заказ за 60 дней
SELECT DISTINCT customer_id FROM orders WHERE days_since <= 60;
Два запроса дают разные ответы, потому что определение «активный» нигде не зафиксировано. dbt решает это так: определение пишется один раз в модели, и все ссылаются на неё.
Частые ошибки
- Думать, что dbt — это новый язык запросов. Нет, это тот же SQL вашего хранилища плюс обвязка.
- Ожидать, что dbt доставит данные. dbt не выгружает данные из источников — он только трансформирует то, что уже в хранилище (об этом — урок про ELT).
- Внедрять dbt ради «модно», не имея боли. Если SQL-трансформаций мало и они стабильны, выгода будет меньше.
Итоги
- До dbt логика трансформаций жила без версий, тестов, документации и порядка запуска.
- dbt закрывает ровно эти четыре боли, оставаясь обычным SQL под капотом.
- Ключевой эффект — единый источник определений и доверие к данным.