dbt

Junior

Как настроить sources.yml в dbt, чтобы устаревшие данные падали громко, а не тихо?

Модель может отработать чисто на таблице, которая не обновлялась три дня. sources.yml — это место, где вы говорите dbt реально это проверять, вместо того чтобы верить, что с апстримом всё в порядке.

Читать на:
Источник не объявлен Объявлен, без freshness Freshness не запускается
Как на практике обычно выглядит покрытие источников у большинства команд — примерно в таком порядке, не измеренная статистика.

Модели dbt могут читать из любой таблицы без объявления её источником — но только объявленный источник получает отслеживание lineage, документацию и проверки freshness. Без них остановившаяся загрузка апстрима выглядит как обычный, успешный прогон.

Объявление источника перед тем, как проверять его freshness

Источник — это декларация в YAML, указывающая на таблицу, которую dbt не строил — обычно это сырые данные, доставленные Fivetran, Airbyte или самописным загрузчиком. Само по себе объявление не меняет, как ваши модели её запрашивают; объявленный источник просто даёт dbt что-то, к чему можно привязать документацию, тесты и конфиг freshness.

# models/staging/sources.yml sources: - name: raw_orders database: analytics schema: raw tables: - name: orders loaded_at_field: _fivetran_synced freshness: warn_after: {count: 6, period: hour} error_after: {count: 24, period: hour}

loaded_at_field — это колонка, максимальное значение которой проверяет dbt — почти всегда это временная метка синхронизации от загрузчика, а не бизнес-колонка с датой (дата заказа и «когда эта строка приземлилась» — это разные вещи, а freshness волнует именно второе).

warn_after против error_after, и как реально запустить проверку

warn_after и error_after — независимые пороги, а не двухступенчатая эскалация одного и того же числа — можно задать порог warn вообще без порога error, если нужна только видимость. Впрочем, ничего из этого не запускается как часть обычного dbt run или dbt build — freshness это отдельная команда:

# проверяет каждый источник с блоком freshness, пишет sources.json dbt source freshness

Это нужно явно планировать — шаг в cron, отдельная задача Airflow, что угодно, что запускается перед моделями, зависящими от этого источника. Блок freshness, который настроен, но никогда не вызывается, не ловит ничего; это не пассивное ограничение, которое dbt применяет сам по себе.

Где здесь всё ещё остаётся пробел

Freshness говорит лишь о том, что в таблицу недавно попала какая-то строка — ничего не говорит о том, разумны ли значения в этой строке, или загрузка записала только половину ожидаемых записей. Источник может пройти проверку freshness и всё равно быть неверным. И ненулевой код выхода dbt source freshness не останавливает downstream-модели, если ваш оркестратор явно не настроен проверять этот код выхода и останавливаться — сам dbt этого за вас не сделает.

Что opti-pipe не проверяет: freshness и конфиг источников целиком живут в sources.yml, который движок правил никогда не читает — он смотрит только на то, что run_results.json сообщает о времени выполнения и статусе уже после того, как прогон произошёл.

Посмотрите, как это выглядит на вашем собственном пайплайне.

Загрузите реальный event log Spark, run_results.json от dbt или экспорт метрик Flink — и получите конкретные рекомендации, которые нужно одобрить, а не ещё одно эмпирическое правило.