История изменений данных

Одна из основных концепций хранилищ данных - это хранение и обработка не только актуальных данных за текущий период, но и за предыдущие. Для владельцев и пользователей различных аналитических систем важно понимать как изменялись данные с течением времени. Для этих целей, как уже было отмечено ранее, в dbt™ реализована функциональность снэпшотов.

Напомню, что в отличие от моделей, которые всегда содержат только актуальное (текущее или последнее) состояние данных, снэпшоты позволяют вести версионность данных, то есть отслеживать изменение данных без потери предыдущих состояний.

Стандартные модели

Снэпшоты

Назначение

Преобразование данных на основе текущего состояния

Отслеживание изменений данных

Материализация

Таблицы или представления с текущими данными

Таблицы истории, доступные только для добавления (append-only)

Механизм формирования снэпшотов

Спэпшоты создаются при выполнении комады dbt snapshot. В момент запуска создается первый «слепок» данных, повторяющий структуру исходной таблицы, изменение которой планируется отслеживать, с дополнительными столбцами, включая dbt_valid_from и dbt_valid_to. При этом у всех записей dbt_valid_to будет иметь значение null.

При последующих запусках dbt™ проверяет, какие существующие записи изменились и были ли созданы новые. Если какая-то существующая запись изменилась, то dbt_valid_to обновит значение, а изменения запишутся в новую строку со значением dbt_valid_to = null. Новая запись, которой ранее не было тоже будет иметь значение dbt_valid_to = null.

Примечание

При настройке снэпшотов в измененных и новых записях существует возможность установить значение '9999-12-31' вместо null для столбца dbt_valid_to.

Также стоит упомянуть о стратегиях выявления изменений.

Таких стратегий всего две:

  • временная метка (timestamp), которая использует столбец updated_at для определения изменения записи;

  • проверка (сheck), которая сравнивает текущие и предыдущее значения столбцов таблицы, чтобы определить, изменилась ли запись.

Стратегия временной метки (timestamp)

Стратегия временных меток используется, когда исходные записи содержат поле, которое обновляется при каждом изменении (например, столбец last_update). Движок dbt™ использует этот столбец, чтобы определить, изменилась ли запись с момента последнего запуска снэпшота.

Чтобы использовать данную стратегию, необходимо указать столбец в настройках снэпшотов. dbt™ сравнивает предыдущее значение с текущим значением при каждом запуске. Если временная метка изменилась, dbt™ рассматривает запись как обновленную, завершает предыдущую версию и вставляет новую запись.

Эта стратегия эффективна, однако требует наличия надежного и постоянно обновляемого столбца временных меток в исходных данных. Если временная метка не изменяется при изменении данных, то dbt™ не выполнит обновление снэпшота.

Стратегия проверки (сheck)

Стратегия проверки применяется в случаях, когда в исходной таблице отсутствует столбец с датой/временем обновления. Эта стратегия работает путем сравнения одного или нескольких столбцов между их текущими и предыдущими значениями (например, check_cols = ["phone", "email"]). Если значение в записи какого-либо из этих столбцов изменилось, то dbt™ аннулирует старую запись и запишет новую. Если значения столбцов идентичны, dbt™ не будет предпринимать никаких действий.

Данная стратегия может быть более затратной с точки зрения вычислений, особенно для широких таблиц или больших наборов данных. Важно выбирать только те столбцы, которые, как ожидается, могут измениться, чтобы избежать ненужного управления версиями. Поэтому разработчиками dbt™ рекомендовано использование стратегии временных меток, так как при этой стратегии требуется отслеживать только одну колонку (updated_at), а также уменьшается вероятность возникновения ошибок (например, если несвоевременно будет обновлена настройка стратегии при изменении схемы таблицы, когда добавляются/удаляются столбцы, участвующие в формировании «слепков»).

Важно

В случае использования стратегии проверки может возникнуть соблазн настроить для отслеживания изменений все столбцы исходной таблицы, указав check_cols = «all». Хотя такая настройка является штатной, но разработчики dbt™ все-таки рекомендуют перечислять конкретные столбцы, которые необходимо проверять, или же рассмотреть возможность использования суррогатного ключа по нескольким столбца. Затем этот ключ указывать в настройках формирования снэпшота.

Процесс построения снэпшотов

Процесс построения снэпшота в dbt™ содержит следующие этапы:

  1. Определение источника.

  2. Настройка и построение модели снэпшота.

  3. Запуск снэпшота.

Определение источника

В качестве источника для снэпшотов можно использовать как таблицы исходной системы, так и модели staging-слоя. На примере одной из staging-моделей проекта отследим изменение контактной информации заказчиков (stg_pg__customers).

Настройка и построение модели «снэпшота»

Примечение

До версии dbt™ 1.9 существовала возможность конфигурации снэпшотов только через SQL синтаксис. Но начиная с версии 1.9, можно обойтись настройками с помощью YAML. Хотя вариант с SQL также продолжает функционировать.

Перед началом работы со снэпшотами рекомендуется обновить версию (минимум до 1.9)

Создайте в папке snapshots файл customers_snapshot.yml и добавьте в него следующий код:

snapshots: - name: customers_snapshot relation: ref('stg_pg__customers') config: schema: snapshots unique_key: customer_id strategy: timestamp updated_at: updated_at dbt_valid_to_current: "cast('9999-12-31' as date)"
Рисунок 68. Конфигурация снэпшота

Запуск снэпшота

Снэпшоты не совсем обычные модели. Как было отмечено ранее, в проекте они хранятся не в общей папке models, а в отдельной snapshots. Более того, для них создается отдельная схема, что является своего рода «защитой от дурака» — потенциального удаления этих таблиц. Поэтому снэпшоты создаются отдельной командой dbt snapshot (или же в рамках общей сборки проекта dbt build).

Выполните в командной строке или терминале команду создания снэпшотов:

dbt snapshot
Примечание

Команда dbt snapshot запускает сразу все имеющиеся снэпшоты. Если требуется запустить какую-то определенную модель, то используйте команду dbt snapshot --select snapshot_name, где snapshot_name — название модели снэпшота.

Например, запуск рассмотренного ранее снэпшота можно было выполнить так:

dbt snapshot --select customers_snapshot

После запуска команды вы сразу увидите лог с информацией об успешности запуска и формировании снэпшотов, или же возникшей ошибке:

Рисунок 69. Запуск снэпшота

Проверьте полученный результат в базе, перейдите в pgAdmin.

Согласно выполненным настройками создалась новая схема snapshots с таблицей customers_snapshot:

1

2

Рисунок 70. Созданный в базе снэпшот

Пример отслеживания изменений

Для примера возьмите произвольную запись и сымитируйте изменение в системе-источнике (таблица public.customer).

select * from public.customer where customer_id = 1;

1

2

3

Рисунок 71. Выбор примера для отслеживания изменений

Предположим, что данный пользователь (Агата Морозова) сменил фамилию и, соответственно, водительское удостоверение. При внесении изменений в исходной системе также обновится значение временной метки.

Выполните следующий запрос для имитации обновления данных в исходной таблице:

update public.customer set last_name='Кристи', driving_licence_number='5716681479', driving_licence_valid_from='2026-01-01', last_update='2026-01-30 09:00:00' where customer_id = 1;

Проверьте еще раз данные выбранного заказчика после обновления, выполните запрос:

select * from public.customer where customer_id = 1;

1

2

3

Рисунок 72. Обновление значений некоторых полей по выбранному примеру

Так как снэпшот customers_snapshot построен на staging-модели stg_pg__customers сначала потребуется обновить данную модель с учетом изменений в исходной таблице customer.

Запустите построение модели stg_pg__customers:

dbt run --select stg_pg__customers
Рисунок 73. Обновление staging-модели с информацией о заказчиках

Посмотрите изменения в базе. Выполните запрос:

select * from staging.stg_pg__customers where customer_id = 1;

1

2

3

Рисунок 73. Проверка staging-модели в базе

Модель staging-слоя в виде представления в базе успешно обновилась. Вернитесь в VS Code или командную строку и повторите команду создания снэпшотов:

dbt snapshot
Рисунок 74. Создание снэпшота

Лог указывает на успешное выполнение задания, поэтому можно смело проверять изменения в базе. Вернитесь pgAdmin и выполните запрос:

Примечание

В выборку для наглядности добавлены поля, значения которых изменились. Но вы можете вывести все поля таблицы.

select customer_id , last_name , driving_licence_number , driving_licence_valid_from , updated_at , dbt_valid_from , dbt_valid_to from snapshots.customers_snapshot where customer_id = 1;

1

2

3

Рисунок 75. Проверка изменений в снэпшоте

Как видно, снэпшот содержит две строки по выбранному заказчику — до и после изменения. Актуальной является та, у которой значение dbt_valid_to равно 9999-12-31 00:00:00.

Таким образом, вы познакомились в функциональностью dbt™ по отслеживанию изменений. Сохраните текущее состояние проекта.

Сохранение проекта в GitHub

Вернитесь в VS Code и подготовьте измененные файлы проекта для отправки на сервер:

git add .

Добавьте сообщение для коммита:

git commit -m "snapshots"

Отправьте локальный проект в репозиторий GitHub:

git push

Теперь актуальный код проекта хранится в GitHub-репозитории.