В прошлом уроке мы разобрали базовые селекторы по имени и направлению в DAG. Но dbt позволяет выбирать узлы и по их свойствам — тегам, пути, типу ресурса, материализации, изменённости. Это и есть «селектор-методы», и они открывают сценарии, без которых не построить нормальный CI.
Синтаксис: method:value
Метод — это префикс в формате имя:значение:
dbt run --select tag:daily
dbt run --select path:models/staging
dbt run --select resource_type:test
dbt run --select config.materialized:incremental
Это говорит dbt: «найди все узлы DAG, у которых указанный атрибут равен указанному значению».
Восемь методов покрывают 90% реальных нужд. Большинство комбинируется с + и + для расширения на соседей в DAG.
tag: — теги
Теги — это произвольные метки, которые ты ставишь моделям в YAML или в {{ config() }} блоке. Они нужны исключительно для удобства селекции.
В YAML:
models:
- name: revenue_daily
config:
tags: ['daily', 'finance']
В Jinja:
{{ config(tags=['daily', 'finance']) }}
select ...
Затем в CLI:
dbt run --select tag:daily # всё с тегом daily
dbt run --select tag:finance # всё с тегом finance
Один узел может иметь много тегов — селектор tag:daily подберёт все, где daily есть в списке.
Стандартные практики тегирования:
tag:hourly | tag:daily | tag:weekly— расписание запускаtag:finance | tag:marketing | tag:ops— доменная зонаtag:pii— модель содержит персональные данные (для compliance-фильтров)tag:slow— известно тяжёлая модель, исключаем в локальной разработке
В dbt_project.yml можно задавать теги массово:
models:
jaffle_shop:
marts:
finance:
+tags: ['finance']
Все модели в models/marts/finance/ получат тег finance автоматически.
path: — по пути в файловой системе
path: фильтрует по пути относительно корня проекта:
dbt run --select path:models/staging
dbt run --select path:models/marts/finance
Это эквивалентно «папочному» селектору (staging или marts.finance), но более явно. Полезно когда название папки совпадает с именем модели — path: снимает неоднозначность.
Также path: поддерживает обычный путь без models/ префикса — для seeds, snapshots, tests:
dbt run --select path:seeds # все seeds
dbt test --select path:tests # все singular tests
resource_type: — тип узла
В DAG dbt живут разные типы узлов:
model— обычные SQL/Python моделиseed— CSV-сидыsnapshot— снэпшотыtest— тесты (generic + singular)source— таблицы-источникиexposure— exposuresanalysis— analysis-файлыmetric— метрики (1.6+)
Фильтрация по типу:
dbt list --select resource_type:model # только модели
dbt list --select resource_type:test # только тесты
dbt list --select resource_type:snapshot # только снэпшоты
В команде dbt build все типы запускаются вместе — но в dbt list или для специфичных операций часто нужно ограничиться одним типом.
config.<param>:<value> — по конфигу
Можно фильтровать узлы по любому конфигу, который задаётся через {{ config() }} или YAML:
dbt run --select config.materialized:incremental
dbt run --select config.materialized:table
dbt run --select config.schema:marketing
Особенно полезно config.materialized:incremental — когда хочется запустить только инкрементальные модели (например, в почасовом крон-джобе).
config.tags:daily — то же, что tag:daily. Но конфиги покрывают вообще всё, включая кастомные параметры:
models:
- name: revenue_daily
config:
meta:
owner: 'finance-team'
dbt run --select config.meta.owner:finance-team
source: — выбор по источнику
source: фильтрует тесты и модели по source, к которому они привязаны:
dbt test --select source:jaffle # все тесты на source jaffle
dbt run --select source:jaffle+ # все модели, зависящие от source jaffle
source:jaffle+ — это «всё, что вниз по DAG от sources в jaffle». Очень частый паттерн для проверки «что у меня сломается, если такой-то источник изменится».
Также можно указать конкретную таблицу: source:jaffle.customers.
state:modified — что изменилось
Самый важный селектор для CI. Чтобы он работал, нужен второй manifest — обычно manifest с предыдущего production-билда, который называется state baseline.
dbt run --select "state:modified" --state ./prod-manifest
dbt сравнит текущий код проекта с предыдущим manifest и выберет только изменённые узлы. Что считается «изменённым»:
- изменён SQL/Python код модели
- изменён
{{ config() }}блок - изменён description, тест, или любой YAML конфиг
- изменилась версия пакета
- новые модели (modified.body)
Подвиды для тонкой фильтрации:
state:modified.body— только SQL/Python кодstate:modified.configs— только конфиги (теги, материализация и т.п.)state:modified.contract— изменились контракты моделиstate:modified.relation— изменилось имя таблицы или схема
В CI типичная команда:
dbt build --select "state:modified+" --state ./prod-manifest
state:modified+ означает «изменённые узлы плюс всё downstream от них». То есть «то, что изменилось, и всё, на что оно повлияет».
Чтобы --state работал, в CI пайплайне нужно сначала скачать manifest.json с прошлого зелёного билда (артефакт из CI или объект из S3), затем дать на него путь через --state. Без этого state:modified упадёт с ошибкой “no state manifest found”.
group: и package:
group: фильтрует по dbt-группе (логическая группа моделей с access-контролем, 1.5+):
dbt run --select group:finance
package: — по пакету (главный проект называется именем из dbt_project.yml, пакеты — именем из packages.yml):
dbt list --select package:dbt_utils
dbt run --select package:jaffle_shop
В junior-проекте обычно одни и те же модели лежат в главном пакете, package: используется реже — пока в проект не подключатся внешние модели через пакеты.
Комбинирование методов с операторами
Все селектор-методы можно комбинировать с +, запятой, пробелом:
# Всё upstream от моделей с тегом daily
dbt run --select +tag:daily
# Всё downstream от моделей в staging
dbt run --select path:models/staging+
# Только инкрементальные модели в папке marts
dbt run --select "config.materialized:incremental path:models/marts"
# Изменённые модели в финансовой группе плюс их downstream
dbt build --select "state:modified group:finance"+ --state ./prod-manifest
Семантика та же, что и для имён: пробел = AND, запятая = OR.
tag:, config.tags: — точное место в YAML
Несколько нюансов:
tag:dailyищет тег в любом конфиге (Jinja, YAML, dbt_project.yml).config.tags:daily— то же самое явно.
Разницы нет, можно писать как удобно.
Распространённые рецепты для CI
Рецепт 1: Минимальный CI-билд после PR
# Скачать manifest с прошлого зелёного билда
aws s3 cp s3://dbt-artifacts/manifest.json ./prod-manifest/manifest.json
# Билд только того, что изменилось
dbt build --select "state:modified+" --state ./prod-manifest
Рецепт 2: «Слим CI» — только тесты на изменённых
# Только тесты на изменённых моделях (быстро, для smoke check)
dbt test --select "state:modified,test_type:generic" --state ./prod-manifest
Рецепт 3: Production-почасовой джоб
# Все инкрементальные модели + тесты
dbt build --select "config.materialized:incremental+,tag:hourly+"
Рецепт 4: Локальная разработка — всё, кроме медленных
dbt run --exclude tag:slow
Рецепт 5: Проверить blast-radius source
# Что сломается, если изменится stg_orders?
dbt list --select stg_orders+ --resource-type model
Попробуй сам
В Jaffle Shop:
-
Затэгай две модели
dailyчерез YAML и{{ config() }}. Запустиdbt run --select tag:daily. -
Список всех тестов:
dbt list --select resource_type:test -
Список всех инкрементальных моделей (если есть):
dbt list --select config.materialized:incremental -
Сделай небольшое изменение в
stg_orders.sql. Скопируй текущийtarget/manifest.jsonв./prod-manifest/manifest.json. Затем измениstg_orders.sqlснова. Запусти:dbt list --select "state:modified" --state ./prod-manifestДолжна выйти
stg_orders. Затемstate:modified+— выйдут все downstream.
Чек-лист
- tag: — для расписаний и доменов (
hourly,daily,finance,pii). - path: — для папок (
path:models/staging). - resource_type: —
model,test,seed,snapshot,source,exposure. - config.materialized: —
view,table,incremental,ephemeral. - source: —
source:jaffleилиsource:jaffle.customers. - state:modified[+/.body/.configs/.contract/.relation] — главный CI-фильтр.
- group: — для access-control групп (1.5+).
- package: — для фильтрации по пакетам.
- Методы комбинируются с
+model+,model+,+model, запятой (UNION), пробелом (INTERSECT). state:modified+(плюс справа) — must-have для CI: «изменённое + downstream».