source(): объявление источников
Где заканчивается ваш DAG и начинаются чужие сырые таблицы — это граница source().
source() — Jinja-функция для ссылки на сырые внешние таблицы (которые загрузил не dbt), объявленные в YAML; в отличие от
ref(), они не строятся dbt, а только читаются.
Зачем отдельная функция для источников
Модели dbt стоят на фундаменте — сырых таблицах, которые в хранилище положил инструмент загрузки (Fivetran, Airbyte). dbt их не создаёт, но читает. Можно было бы писать from raw.customers напрямую, но это плохо: имя схемы захардкожено, зависимость от источника невидима, и нельзя протестировать «свежесть» данных. source() решает всё это.
Объявление источника в YAML
# models/staging/_sources.yml
version: 2
sources:
- name: raw # логическое имя источника
schema: raw # реальная схема в хранилище
tables:
- name: customers
description: "Сырые клиенты из CRM"
- name: orders
description: "Сырые заказы из биллинга"
loaded_at_field: created_at
freshness: # проверка свежести данных
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}
Ссылка на источник в модели
Теперь вместо хардкода raw.customers в модели пишут source('raw', 'customers'):
-- models/staging/stg_customers.sql
select
id as customer_id,
lower(email) as email
from {{ source('raw', 'customers') }}
Проверка свежести источника
Раз источник объявлен с loaded_at_field, dbt умеет проверять, не устарели ли данные:
# Проверить свежесть всех источников
dbt source freshness
Если последняя загрузка старше порога — dbt предупредит или упадёт с ошибкой. Это ловит проблему «труба загрузки сломалась, а мы строим витрины на вчерашних данных».
source() против ref()
| Функция | На что ссылается | Строит ли dbt |
source() | Сырьё, загруженное извне | Нет, только читает |
ref() | Другую модель dbt | Да, строит и упорядочивает |
Как работает под капотом
Источники — это «листья» в начале DAG: у них нет того, что dbt строит, но они дают графу точку входа. {{ source('raw', 'customers') }} компилируется в полное имя raw.customers, взятое из YAML. Зависимость модели от источника тоже попадает в граф, поэтому в документации видно, какие витрины завязаны на какой источник — это бесценно при анализе влияния (lineage).
Частые ошибки
- Хардкодить сырую таблицу в FROM. Теряется lineage, проверка свежести и переносимость — используйте
source(). - Путать source() и ref(). Сырьё извне —
source(); модель dbt —ref(). - Строить витрины прямо на источниках. Лучше сперва обернуть источник в staging-модель (об этом — раздел про слои).
Итоги
source()ссылается на сырые внешние таблицы, объявленные в YAML; dbt их читает, но не строит.- Источники дают lineage, переносимость и проверку свежести (
dbt source freshness). - Сырьё —
source(), модели dbt —ref().