Большинство команд dbt принимает флаг --select (или --exclude). С его помощью указываешь, какие именно узлы DAG обрабатывать — одну модель, всю ветку, или сложное пересечение нескольких множеств. Это похоже на git с его рефспеками: маленький синтаксис, но огромный рычаг.
Базовая идея
Без --select команда работает со всем DAG:
dbt run # запустить все модели
dbt test # запустить все тесты
dbt build # построить всё подряд
С --select — только указанное подмножество:
dbt run --select customers # только модель customers
dbt run --select staging.stg_orders # только модель в подпапке staging
dbt run --select +customers # customers + всё, от чего она зависит
--exclude работает наоборот — вычитает из результата:
dbt run --exclude tag:slow # запустить всё, кроме моделей с тегом slow
Семь операторов формируют 95% повседневного использования. + и @ — направление в графе, пробел и запятая — комбинирование множеств.
Простое имя — одна модель
Самый простой селектор — имя модели:
dbt run --select customers
Это запустит ровно одну модель customers.sql. Никакие upstream-зависимости не пересоздаются — dbt предполагает, что они уже актуальны в warehouse. Это удобно когда ты дебажишь конкретную модель и не хочешь ждать пересборки всего staging.
Имена можно указывать без расширения и без пути — dbt находит уникальное соответствие. Если у тебя две модели с одинаковым именем в разных папках (что само по себе плохой паттерн), dbt упадёт с ошибкой про коллизию.
+model — модель и всё, от чего она зависит
Префикс + означает «эта модель и весь её upstream»:
dbt run --select +customers
Это запустит:
- все staging-модели, на которые ссылается
customersчерезref() - все intermediate-модели, через которые проходит линия
- саму
customers
Это самый частый паттерн дебага: «я хочу собрать customers, и убедиться, что под ней свежий стейджинг». Без + ты можешь получить customers, посчитанную по старым staging-таблицам в warehouse.
Можно ограничить глубину: 1+customers — только модель и её прямые родители (один шаг upstream). 2+customers — два шага. Без числа — весь корень.
model+ — модель и всё, что от неё зависит
Постфикс + означает «эта модель и весь её downstream»:
dbt run --select stg_orders+
Это запустит:
- саму
stg_orders - все intermediate, которые её используют
- все marts, которые в итоге опираются на
stg_orders
Используется когда ты поменял базовую staging-модель и хочешь убедиться, что все зависящие от неё пересоберутся. В CI после изменения staging это критично — иначе marts будут считать по старому staging.
Также можно ограничить: stg_orders+1 — только сама и прямые потомки (один шаг). stg_orders+2 — два шага вниз.
+model+ — модель и всё в обе стороны
Комбинируем оба:
dbt run --select +customers+
Запустит:
- всё, от чего зависит
customers(upstream) - саму
customers - всё, что зависит от
customers(downstream)
То есть всю вертикаль через эту модель. Полезно для «полного rebuild через критическую модель».
@model — особый случай
Оператор @ похож на +model+, но не симметричен:
dbt run --select @customers
Это означает: «всё upstream от customers, плюс downstream от каждого upstream, не только от самой customers». То есть для каждой родительской модели берётся её собственный downstream.
Зачем такое нужно? Сценарий «я меняю staging-модель и хочу пересобрать ВСЁ, что зависит от любого из её родителей-источников». Например, если изменилась stg_orders, @stg_orders пересоберёт не только модели, использующие stg_orders, но и все другие модели, использующие тех же родителей, что stg_orders.
В практике junior используется редко. Главное — знать, что это не то же самое, что +model+.
Несколько селекторов через запятую: union
Запятая (без пробелов!) — это объединение множеств:
dbt run --select customers,orders,revenue_daily
Запустит ровно три модели. Эквивалентно «customers OR orders OR revenue_daily».
С графовыми операторами:
dbt run --select +customers,+orders
Запустит customers + её upstream, ПЛЮС orders + её upstream. Если upstream пересекается (например, обе модели зависят от stg_customers) — она войдёт в множество один раз, но не дважды запустится.
Запятая БЕЗ пробелов! +customers, +orders (с пробелом) — это уже два аргумента: первый аргумент +customers,, второй +orders. Многие shell’ы трактуют их как intersection.
Пробел — intersection
Пробел между селекторами — это пересечение множеств:
dbt run --select "tag:daily marts.*"
Это «модели с тегом daily, И находящиеся в папке marts». Только те, что в обоих множествах одновременно.
Используется когда нужно сузить выборку по нескольким условиям. Пример: «пересобери модели в marts, у которых тег finance, И которые были модифицированы в этом PR»:
dbt run --select "tag:finance marts.* state:modified"
Не забывай кавычки — иначе shell сам разрежет аргумент по пробелам.
Сравнение union vs intersection
Запятая объединяет (логическое OR). Пробел пересекает (логическое AND). Это две принципиально разные операции.
Это два совершенно разных множества. Junior часто путают и не понимают, почему dbt run «не делает ничего». Если выборка пустая — проверь, не пересечение ли вместо объединения.
--exclude — вычитание
--exclude принимает тот же синтаксис, что --select, но вычитает множество из текущего:
dbt build --select +customers --exclude tag:slow
Что произойдёт:
- Сначала составится множество
+customers(customers + её upstream) - Затем из этого множества выкинутся все модели с тегом slow
- Запустится остаток
Полезно когда в большом графе есть «дорогие» модели, которые ты не хочешь трогать в локальной разработке.
Несколько --select
Можно передать несколько --select подряд — это эквивалентно union:
dbt run --select customers --select orders
# эквивалентно
dbt run --select customers,orders
Иногда так писать удобнее в скриптах, где аргументы собираются программно. Эффект тот же.
Пути и папки
dbt трактует имя как путь, если в нём есть . или /:
dbt run --select staging
# то же что
dbt run --select "path:models/staging"
Это даёт способ выбрать «всё в этой подпапке»:
dbt run --select staging
dbt run --select marts.finance
dbt run --select intermediate.payments
Точка — разделитель уровней в иерархии папок (как python-импорты).
Глобы (*)
Звёздочка работает как glob:
dbt run --select stg_*
dbt run --select "marts.finance.*"
Это выберет все модели, чьи имена начинаются с stg_, или все модели в models/marts/finance/. Полезно когда префиксы консистентные.
Попробуй сам
В тестовом проекте Jaffle Shop (или своём):
# Только модель customers
dbt run --select customers
# Customers + всё, от чего она зависит
dbt run --select +customers
# Customers + всё, что от неё зависит
dbt run --select customers+
# Всё в папке marts, кроме revenue_daily
dbt run --select "marts.*" --exclude revenue_daily
# Только модели с тегом daily, в папке marts
dbt run --select "tag:daily marts.*"
# Union двух множеств
dbt list --select customers,orders
Сравни выводы, посмотри, какие модели включились/исключились.
Чек-лист
--select customers— ровно эта модель.+customers— она и весь upstream.customers+— она и весь downstream.+customers+— вся вертикаль через неё.@customers— особый случай: upstream + downstream от каждого upstream.a,b(запятая, без пробелов) — UNION.a b(пробел, в кавычках) — INTERSECTION.--exclude— вычесть из текущего множества.- Точка в имени = путь к подпапке.
*— glob.