Learning Platform
Глоссарий Troubleshooting
Урок 06.04 · 15 мин
Начальный
overridespackagesschema overridedatabase overridemetatags

Когда мы установили dbt-utils или dbt-jaffle-shop через packages.yml, в проект приходит готовый набор моделей, тестов и sources — но эти sources указывают на схему/базу, которая есть у автора пакета, а не у тебя. Чтобы заставить пакетные модели читать из твоего warehouse, нужно переопределить source.

В этом уроке разберём, как это работает, и заодно дополнительные тонкости: schema/database override на уровне проекта, meta-поля и tags.

Зачем переопределять source

Простой сценарий: ты установил демо-package dbt-jaffle-shop, который ожидает source с именем jaffle_shop в схеме dbt_jaffle_shop_raw. У тебя в DuckDB raw-данные лежат в main, в файле jaffle_shop.duckdb. Без override модели пакета будут компилироваться в FROM dbt_jaffle_shop_raw.customers и падать с Catalog Error.

Решение: переопределить source в своём _sources.yml.

Конфликт между source из пакета и реальностью

Package декларирует source со своими database/schema. Проект использует source через ref/select, но физическая таблица лежит в другом месте. Override решает конфликт без форка пакета.

Package _sources.ymlschema: dbt_jaffle_shop_raw
Models in packagesource('jaffle_shop', 'orders') -> dbt_jaffle_shop_raw.orders
My warehouseschema: main, file: ./jaffle_shop.duckdb
mismatchБез override модели пакета будут пытаться SELECT FROM dbt_jaffle_shop_raw.orders, которой нет в моём warehouse. Compilation проходит, runtime падает.
My _sources.ymloverrides: dbt_jaffle_shop_pkg
Resultsource('jaffle_shop', 'orders') -> main.orders

Синтаксис override

В своём YAML добавляешь источник с тем же name, что и в пакете, плюс ключ overrides:, указывающий имя пакета:

version: 2

sources:
  - name: jaffle_shop
    overrides: dbt_jaffle_shop_pkg
    database: jaffle_shop
    schema: main
    tables:
      - name: orders
      - name: customers
      - name: payments

Ключевая магия:

  • overrides: dbt_jaffle_shop_pkg — говорит dbt: “это не отдельный source, это переопределение того, что декларирует пакет dbt_jaffle_shop_pkg”.
  • Поля database, schema подменяют пакетные значения.
  • Поле tables тоже можно переопределить — например, поменять identifier отдельных таблиц.

После такого override все модели пакета, которые используют source('jaffle_shop', 'orders'), начнут читать из jaffle_shop.main.orders (то есть из твоего warehouse), а не из dbt_jaffle_shop_pkg’овского dbt_jaffle_shop_raw.orders.

Что можно переопределить

Через overrides можно подменить почти всё, что декларирует пакет:

sources:
  - name: jaffle_shop
    overrides: dbt_jaffle_shop_pkg

    # Уровень source
    database: my_db
    schema: my_schema
    loader: my_loader
    loaded_at_field: my_loaded_at
    freshness:
      warn_after: { count: 6, period: hour }
      error_after: { count: 24, period: hour }
    meta:
      owner: data-platform-team

    # Уровень отдельных таблиц
    tables:
      - name: orders
        identifier: real_orders_table  # имя в warehouse
        loaded_at_field: dbt_loaded_at  # подменяем для конкретной таблицы
        tags: [pii, critical]

Если поле не указано в override — берётся из пакетной декларации. Это и есть смысл “override”: ты подменяешь только то, что отличается, не дублируешь весь YAML.

Schema override на уровне проекта

Помимо source-override, есть более общий механизм — schema override. Он работает не на sources, а на моделях. dbt по умолчанию строит модели в схеме target.schema (из profiles.yml). Можно настроить, чтобы модели в разных папках уходили в разные схемы.

В dbt_project.yml:

models:
  jaffle_shop:
    staging:
      +schema: staging  # модели здесь идут в <target_schema>_staging
    marts:
      core:
        +schema: marts   # модели здесь идут в <target_schema>_marts

Если target.schema = analytics, то реально модели окажутся в analytics_staging и analytics_marts. Это полезно для организации больших проектов, но к sources напрямую не относится — sources не зависят от target.schema, они полностью описаны в _sources.yml.

WARNING

+schema в dbt_project.yml — это суффикс, а не полное имя. dbt добавляет его к target.schema через нижнее подчёркивание. Поведение по умолчанию: generate_schema_name macro комбинирует. Можно переопределить эту macro, но junior’у пока не нужно — на старте достаточно понимать, что schema name = target.schema + _ + custom_schema (если указан).

Database override на уровне проекта

Аналогично schema есть +database:

models:
  jaffle_shop:
    marts:
      +database: analytics_prod  # модели здесь идут в другую базу

Используется реже. На DuckDB вообще нет смысла менять database из-под dbt — база = файл, и dbt не умеет открывать сразу несколько файлов без ATTACH. На Snowflake/BigQuery полезно: например, mart-модели в prod_analytics, staging в prod_staging.

meta: и tags: для organization

Source-декларация поддерживает два важных поля — meta: и tags:. Они не влияют на компиляцию, но важны для organization, документации и автоматизации.

sources:
  - name: stripe
    database: raw
    schema: stripe
    meta:
      owner: payments-team
      pii_level: high
      contains_pii: true
    tags: [pii, payments, critical]
    tables:
      - name: charges
        meta:
          retention_days: 365
        tags: [billing]
  • meta — произвольный словарь, доступен в Jinja через graph.sources['source.<project>.<name>.<table>'].meta. Применяется для custom-логики: например, autogenerated docs, alert-rules, data lineage экспорт.
  • tags — список строк. Используется в --select tag:pii для node selection. Можно запустить dbt test --select tag:pii, чтобы тестировать только PII-таблицы.
TIP

В dbt 1.10+ много полей source раньше были top-level, а теперь должны быть под meta:. Например, custom-property data_owner: alice без обёртки в meta даст warning. Если видишь предупреждение Custom top-level property 'data_owner' on source — оберни в meta.

Полный пример с override

Допустим, мы используем пакет jaffle_shop от dbt Labs. Он декларирует:

# packages/dbt_jaffle_shop_pkg/models/staging/_sources.yml
sources:
  - name: jaffle_shop
    database: raw
    schema: jaffle_shop_raw
    tables:
      - name: customers
      - name: orders
      - name: payments

У нас в проекте warehouse — DuckDB-файл ./jaffle_shop.duckdb, схема main, таблицы называются raw_customers, raw_orders, raw_payments. Чтобы пакетные модели заработали:

# models/_sources_overrides.yml
version: 2

sources:
  - name: jaffle_shop
    overrides: dbt_jaffle_shop_pkg
    database: jaffle_shop
    schema: main
    tables:
      - name: customers
        identifier: raw_customers
      - name: orders
        identifier: raw_orders
      - name: payments
        identifier: raw_payments

Что произойдёт: модели в пакете, например stg_customers.sql, продолжают писать:

SELECT * FROM {{ source('jaffle_shop', 'customers') }}

Но dbt видит override и компилирует это в:

SELECT * FROM jaffle_shop.main.raw_customers

Пакет не нужно форкать или модифицировать. Override — это твоя локальная адаптация.

Когда override НЕ нужен

Не каждый проект использует пакеты. Если у тебя только свой _sources.yml без overrides:, ты работаешь с обычной декларацией. Override — это инструмент исключительно для тех случаев, когда чужой YAML диктует имена.

Если ты сам контролируешь source — просто меняй database/schema в своём YAML, никаких overrides не надо.

Когда override, когда обычная декларация

Если sources объявлены тобой — меняешь напрямую. Если приходят из пакета — нужен override. В смешанных проектах могут быть оба варианта.

Свой _sources.ymlбез overrides
Меняй database/schema напрямуюэто твой YAML
Source из packagedbt_utils, jaffle_shop, fivetran transformations
overrides: <pkg_name>в своём YAML

Попробуй сам

Если у тебя установлен пакет dbt_utils, у него тоже есть свои тестовые sources — но они нужны только для unit-тестов внутри пакета и тебя не задевают. Для практики проще симулировать ситуацию вручную.

  1. Создай models/_sources.yml с обычной декларацией:
version: 2

sources:
  - name: jaffle_shop
    database: jaffle_shop
    schema: main
    tables:
      - name: customers
  1. Поменяй schema на несуществующую: schema: nonexistent. Запусти dbt compile --select stg_customers (если у тебя есть такая модель). Увидишь, что в скомпилированном SQL появилось nonexistent.customers, и при dbt run упадёт Catalog Error.

  2. Поменяй обратно schema: main, но добавь meta: { owner: my-team } и tags: [pii]. Запусти dbt list --select tag:pii — должна показаться твоя таблица.

Это тренирует понимание, что декларация — это просто YAML, который dbt парсит и применяет при компиляции.

Что мы поняли

Source overrides — это механизм переопределения source-декларации, когда она приходит из package. Используется ключевое поле overrides: <package_name>, остальные поля (database, schema, freshness, tables) подменяют пакетные значения. На уровне проекта дополнительно есть +schema и +database в dbt_project.yml — но они влияют на модели, а не на sources. Поля meta: и tags: дают организационные возможности: автоматизация, selection, документация.

На этом мы закрыли тему sources в junior-курсе. В следующем модуле разберём, как dbt материализует модели — view, table, ephemeral, incremental, и почему выбор стратегии критичен для производительности.

Проверка знанийKnowledge check
Ты установил пакет dbt_jaffle_shop_pkg, у него source 'jaffle_shop' с schema 'jaffle_shop_raw'. В твоём warehouse таблицы лежат в schema 'main'. Что нужно прописать в своём _sources.yml, чтобы пакетные модели начали читать из main?
ОтветAnswer
Нужно добавить override с тем же name source и ключом overrides указывающим на пакет: name: jaffle_shop, overrides: dbt_jaffle_shop_pkg, schema: main (и при необходимости database). Это переопределит schema/database из пакета, не требуя его форка. Tables можно тоже переопределить через identifier, если имена отличаются от тех, что в пакете.

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

Результат: 0 из 0
Концептуальный
Вопрос 1 из 6. Когда нужен source override?

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

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

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

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