Отто разбирает весну: «Почему у Уралмаша в апреле подскочили опоздания?» Ты открываешь отчёт «курьеры по зонам» и видишь странное. Отчёт берёт зону курьера из couriers. Курьер Олег сегодня числится в Уралмаше, и все его весенние доставки отчёт записывает Уралмашу, хотя в апреле Олег работал в Центре. Таблица couriers знает только, где курьер сейчас. Когда его перевели, старое значение zone_id просто перезаписали. Истории нет, и вопрос Отто без неё не решить.
Штампы в паспорте
В паспорте не стирают старую прописку, когда человек переезжает. Старый штамп остаётся, на нём пишут дату выписки, а рядом ставят новый. Можно в любой момент сказать, где человек жил в марте прошлого года.
Снапшот в dbt ведёт такую историю для строк таблицы: старую версию не перезаписывает, а закрывает датой, и рядом дописывает новую.
SCD type 2
Такой способ хранения истории называют SCD type 2: медленно меняющееся измерение второго типа. Справочник курьеров меняется редко, но меняется. Первый тип просто перезаписывает строку, как сейчас делает couriers. Второй хранит все версии.
Снапшот в dbt добавляет к копии таблицы четыре служебные колонки:
| Колонка | Что в ней |
|---|---|
dbt_valid_from | с какого момента версия действует |
dbt_valid_to | до какого момента; null у текущей версии |
dbt_updated_at | момент, по которому версия получена |
dbt_scd_id | уникальный ключ версии, хэш от ключа и времени |
Где курьер работал 15 апреля, отвечает запрос с условием dbt_valid_from <= '2026-04-15' and (dbt_valid_to > '2026-04-15' or dbt_valid_to is null).
Снапшот в YAML
В dbt 1.12 снапшот описывают в YAML в папке snapshots/:
# snapshots/couriers.yml
snapshots:
- name: couriers_snapshot
relation: source('raw', 'couriers')
config:
unique_key: id
strategy: check
check_cols: ["zone_id", "transport"]
relation говорит, с какой таблицы снимать историю. unique_key это ключ, по которому dbt узнаёт «ту же самую» строку в новом запуске. В старых проектах и статьях снапшот пишут SQL-файлом с блоком {% snapshot %}. Так тоже работает, но новый способ короче.
урок из курса
Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.