dbt
SeniorКак сделать, чтобы CI не пересобирал весь dbt-проект при каждом запуске?
dbt по умолчанию собирает всё. State-based selection — единственное, что делает стоимость CI пропорциональной тому, что реально изменилось, а не размеру проекта.
Проект dbt с 40 моделями и проект с 400 выполняют одну и ту же команду dbt build — и платят за это совершенно разные счета за CI, если только что-то реально не сообщает dbt, что изменилось.
Что на самом деле сравнивает state-based selection
После каждого успешного запуска dbt записывает manifest.json, который полностью описывает скомпилированный SQL каждой модели и её место в DAG. --select state:modified+ сравнивает текущий manifest с сохранённым, на который вы указываете, и собирает только те модели, чей скомпилированный SQL реально изменился, плюс всё, что от них зависит ниже по графу.
Почему это незаметно никогда не срабатывает
Самая частая причина, по которой state selection ничего не даёт: CI никогда не сохранял и не подтягивал manifest предыдущего запуска, так что --state не с чем сравнивать. dbt не выдаёт ошибку — он просто не может найти изменённые модели относительно ничего, и сборка молча делает всё подряд. Исправление — относиться к manifest.json как к артефакту CI, который загружается после каждого успешного прод-запуска и скачивается в начале следующего.
Другой незаметный убийца: привычка к full-refresh
Флаг --full-refresh, оставленный в команде CI «на всякий случай», пересобирает каждую инкрементальную модель с нуля независимо от того, что нашла state selection — для этих моделей diff полностью игнорируется. Обычно это остаток от отладки одной сломанной инкрементальной модели, который так и не убрали. Оставьте --full-refresh для явного, осознанного запуска по одной модели, а не для постоянного флага CI.
Признак: если время сборки CI зависит от размера всего проекта, а не от размера diff в PR — state selection на самом деле не работает: сначала проверьте отсутствующий manifest в --state, затем — затесавшийся --full-refresh.
Посмотрите, как это выглядит на вашем собственном пайплайне.
Загрузите реальный event log Spark, run_results.json от dbt или экспорт метрик Flink — и получите конкретные рекомендации, которые нужно одобрить, а не ещё одно эмпирическое правило.