avatar
дата инженеретта
@data_engineerette
30.04.2026 13:52
Data Vault за один вечер

Решила я тут погрузиться в дата волт на практике. Нашла интересный проект — AutomateDV (бывший dbtvault)

У них есть демо-проект, в котором создаются разные сущности, несколько видосов с объяснениями и небольшая, но очень детальная дока

Поставила себе по инструкции dbt-core, dbt-postgres:


python -m pip install dbt-core dbt-postgres


Подключила AutomateDV — это просто пакет в dbt-проекте, задается в packages.yml:


dbt deps


Подняла постгрю в докере, настроила коннекшены, создала проект:


dbt init


Сгенерила данные из датасета TPC-H и положила их в volume:


pip install tpchgen-cli
mkdir data
tpchgen-cli -s 1 -f csv -o ./data


Создала таблицы и загрузила в них данные:


COPY region FROM '/var/lib/postgresql/data/data/region.csv' DELIMITER ',' CSV HEADER;


Поначалу я смотрела видосы и делала все ручками. Потом забила и чисто запускала модельки, смотрела, что получается. Фреймворк автоматизирует создание дата волта. Во-первых, для стейджинга можно использовать такие поля:

derived_columns - новые поля
hashed_columns - поля для хэширования

Тут мы добавили поле как алиас другого, поле с константной строкой, сделали хэш из 2х первичный ключей:


{%- set yaml_metadata -%}
source_model: 'raw_orders'
derived_columns:
CUSTOMER_KEY: 'CUSTOMERKEY'
RECORD_SOURCE: '!TPCH-ORDERS'
hashed_columns:
ORDER_CUSTOMER_PK:
- 'CUSTOMER_KEY'
- 'ORDERKEY'
...


Во-вторых, создание самих сущностей происходит с помощью удобных макросов:


automate_dv.stage()
automate_dv.hub()
automate_dv.sat()
automate_dv.link()
automate_dv.pit()
...


Все модельки можно позапускать, а потом сгенерить доку по проекту:


dbt run -s +v_stg_orders
dbt run -s hub_customer

dbt docs generate
dbt docs serve


Но саааамое прикольное — это после компиляции моделек зайти в папку target/ и посмотреть, что там нагенерилось. И еще сходить в исходный код самого пакета в dbt_packages/

А нагенерилось там вот такое:


—хэширование нескольких полей
DECODE(MD5(NULLIF(CONCAT_WS('||',
COALESCE(NULLIF(UPPER(TRIM(CAST(CUSTOMER_KEY AS VARCHAR))), ''), '^^'),
COALESCE(NULLIF(UPPER(TRIM(CAST(ORDERKEY AS VARCHAR))), ''), '^^')
), '^^||^^')), 'hex') AS ORDER_CUSTOMER_PK,


—отбор по rn для инсерта в линки
ROW_NUMBER() OVER(
PARTITION BY rr.ORDER_CUSTOMER_PK
ORDER BY rr.LOAD_DATE
) AS row_number

—отбор уникальных значений в сателлит по хешу
WHERE b.INVENTORY_HASHDIFF != b.prev_hashdiff


В общем, интересно поковыряться, как они придумали, и вдохновиться, если у вас сложнее/что-то забыли учесть/еще не реализовали

@data_engineerette
🔥 15
7
🤔 5
12 52 2K

Обсуждение 12

Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.

Обсудить в Telegram