Learning Platform
Глоссарий Troubleshooting
Урок 18.02 · 20 мин
Начальный
SelectorsDAG--select--excludeNode selection

Большинство команд 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% повседневного использования. + и @ — направление в графе, пробел и запятая — комбинирование множеств.

customersровно одна модель
+customerscustomers + вверх по DAG
customers+customers + вниз по DAG
+customers+всё вверх и вниз
@customersвверх + downstream от upstream
a,bunion (объединение)
a bintersection (пересечение) — пробел

Простое имя — одна модель

Самый простой селектор — имя модели:

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) — она войдёт в множество один раз, но не дважды запустится.

WARNING

Запятая БЕЗ пробелов! +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

Запятая vs пробел

Запятая объединяет (логическое OR). Пробел пересекает (логическое AND). Это две принципиально разные операции.

--select tag:daily,marts.*UNION: все с тегом daily ИЛИ в папке marts
--select "tag:daily marts.*"INTERSECT: только те, что и daily, И в marts

Это два совершенно разных множества. Junior часто путают и не понимают, почему dbt run «не делает ничего». Если выборка пустая — проверь, не пересечение ли вместо объединения.


--exclude — вычитание

--exclude принимает тот же синтаксис, что --select, но вычитает множество из текущего:

dbt build --select +customers --exclude tag:slow

Что произойдёт:

  1. Сначала составится множество +customers (customers + её upstream)
  2. Затем из этого множества выкинутся все модели с тегом slow
  3. Запустится остаток

Полезно когда в большом графе есть «дорогие» модели, которые ты не хочешь трогать в локальной разработке.


Несколько --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.
Slim CI и state-aware selection
Проверка знанийKnowledge check
Тебе нужно: пересобрать только marts, которые в папке finance, имеют тег daily, и при этом исключить snapshot-модели. Какой селектор подойдёт? Объясни, почему именно такой и почему запятая или пробел в другом месте дадут не то.
ОтветAnswer
Правильный селектор: dbt build --select "tag:daily marts.finance.*" --exclude resource_type:snapshot. Здесь пробел между tag:daily и marts.finance.* — это intersection: возьми только те модели, которые И с тегом daily, И в папке marts/finance. Запятая дала бы union — все модели с тегом daily плюс все модели в marts/finance, что слишком много. --exclude вынимает snapshots из получившегося множества по селектор-методу resource_type:. Если бы написали --select "tag:daily,marts.finance.*" — это union, в результате попали бы daily-теговые модели из staging и intermediate, не только из marts.finance.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 7. Что запустит команда dbt run --select +customers?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4