dbt snapshots на собеседовании Data Engineer

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.

Зачем спрашивают на собесе DE

Snapshots — встроенный SCD2 механизм dbt. На собесе DE: «зачем snapshots», «timestamp vs check», «как использовать в моделях».

Что делает snapshot

Снимает SCD Type 2 «слепок» source-таблицы. При запуске:

  1. Считывает текущее состояние source.
  2. Сравнивает с last known state в snapshot table.
  3. Изменения → закрывает старую версию (valid_to = now()), вставляет новую с valid_from = now().
  4. Новые записи → INSERT с valid_from = now(), valid_to = NULL.
{% snapshot dim_customer_history %}
  {{ config(
      target_schema='snapshots',
      unique_key='customer_id',
      strategy='timestamp',
      updated_at='updated_at'
  ) }}

  SELECT * FROM {{ source('crm', 'customers') }}
{% endsnapshot %}

dbt snapshot — отдельная команда (не часть dbt run).

Strategy: timestamp

Самый простой. Источник имеет колонку updated_at — dbt сравнивает.

strategy='timestamp'
updated_at='updated_at'

Если updated_at source-row изменился → версия закрыта, новая создана.

Требует. Источник honest'но обновляет updated_at при изменении.

Strategy: check

Без updated_at. dbt сравнивает значения колонок поколoно.

strategy='check'
check_cols=['name', 'email', 'address']
# или
check_cols='all'

Любое изменение в colmun → новая версия.

Минус. Дороже (full column comparison каждый snapshot run).

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Колонки snapshot

Каждая запись имеет:

  • dbt_scd_id — surrogate key (hash of natural key + valid_from).
  • dbt_updated_at — момент loading в snapshot.
  • dbt_valid_from — начало validity.
  • dbt_valid_to — конец validity (NULL для current version).
SELECT customer_id, name, email,
       dbt_valid_from, dbt_valid_to
FROM dim_customer_history
ORDER BY customer_id, dbt_valid_from;

Использование

Текущая версия:

SELECT * FROM dim_customer_history WHERE dbt_valid_to IS NULL

Точка во времени. Какие customers были на 2026-04-01:

SELECT * FROM dim_customer_history
WHERE dbt_valid_from <= '2026-04-01'
  AND (dbt_valid_to > '2026-04-01' OR dbt_valid_to IS NULL)

Использование в downstream models:

{{ config(materialized='TABLE') }}

SELECT * FROM {{ ref('dim_customer_history') }}
WHERE dbt_valid_to IS NULL

Частые ошибки

Запускать dbt run вместо dbt snapshot. Snapshots не запускаются обычным run. Отдельный command.

Удалять записи из source. Snapshot их не удалит. Они останутся с valid_to=NULL забытыми. Нужно явное is_deleted флаг.

Изменять source schema. Snapshot не handle schema change automatic. Manually re-create или migrate.

Strategy=check на больших данных. Дорого. Использовать timestamp если возможно.

Игнорировать dbt_scd_id. Если строишь фактовые таблицы поверх — используй dbt_scd_id как FK к dim history (а не natural key + дата вручную).

Не делать backup перед изменениями. Snapshot — append-only. Но manual modifications могут поломать integrity.

Связанные темы

FAQ

Можно ли удалять старые версии?

Можно. Дополнительные модели поверх snapshot, retention rules.

dbt snapshots — это SCD2?

Да, по сути. Можно расширять до SCD3, SCD6 через дополнительные колонки.

Это официальная информация?

Нет. Статья основана на документации dbt 1.7+.


Тренируйте Data Engineering — откройте тренажёр с 1500+ вопросами для собесов.