
Millistel pĂ”himĂ”tetel on ideaalne Andmete SĂ€ilitamine ĂŒles ehitatud?
Fookus Ă€rivÀÀrtusele ja analĂŒĂŒtikale ilma boilerplate koodita. DWH haldamine nagu koodibaas: versioonimine, ĂŒlevaatus, automaatne testimine ja CI. Moodulsus, laienemisvĂ”ime, avatud lĂ€htekood ja kogukond. KasutajasĂ”bralik dokumentatsioon ja sĂ”ltuvuste visualiseerimine (Data Lineage).
KĂ”igest sellest pĂ”hjalikumalt ja DBT rollist Big Data & Analytics ökosĂŒsteemis â tere tulemast allapoole.
Tere kÔigile
Olge ĂŒhenduses, Artemy Kozyr. Juba rohkem kui 5 aastat olen töötanud andmesalvestites, tehes ETL/ELT ehitust, samuti andmeanalĂŒĂŒsi ja visualiseerimist. Praegu töötan ma , Ă”petan OTUS-es kursusel , ja tĂ€na tahan teiega jagada artiklit, mille ma kirjutasin seoses uue kursuse vastuvĂ”tu algusega.
LĂŒhike ĂŒlevaade
DBT raamistik â see on kĂ”ik T kohta akronĂŒĂŒmis ELT (Extract â Transform â Load).
Kuna sellised vĂ”imsad ja skaleeritavad analĂŒĂŒsibaasid nagu BigQuery, Redshift ja Snowflake on tekkinud, pole enam mingit mĂ”tet teha transformatsioone vĂ€ljaspool Andmete SĂ€ilitamist.Â
DBT ei salvesta andmeid allikatest, kuid pakub tohutuid vÔimalusi töötamiseks juba laaditud andmetega Hoiuses (Internal vÔi External Storage).

DBT peamine eesmÀrk on vÔtta kood, kompileerida see SQL-iks ja tÀita kÀsud Ôiges jÀrjestuses Hoiuses.
DBT projekti struktuur
Projekt koosneb kahest tĂŒĂŒpi kataloogidest ja failidest:
- Mudel (.sql) â transformatsiooni ĂŒksus, vĂ€ljendatud SELECT-pĂ€ringuna
- Konfiguratsioonifail (.yml) â parameetrid, seaded, testid, dokumentatsioon
PÔhitasandil töö toimub jÀrgmiselt:
- Kasutaja valmistab mudelite koodi ette igas mugavas IDE-s
- CLI abil kutsutakse esile mudelite kÀivitamine, DBT kompileerib mudelite koodi SQL-iks
- Kompileeritud SQL-kood tÀidetakse Hoiuses antud jÀrjestuses (graaf)
Nii vÔib CLI kÀivitus vÀlja nÀha:

Kohustuslik on SELECT
See on Data Build Tool raamistiku killer-feature. TeisisÔnu, DBT abstraktsioonib kogu koodi, mis on seotud teie pÀringute materialiseerimisega Hoiuses (variatsioonid kÀskudest CREATE, INSERT, UPDATE, DELETE ALTER, GRANT jne).
Igast mudelist eeldatakse ĂŒhe SELECT-pĂ€ringu kirjutamist, mis mÀÀratleb saadud andmestiku.
Transformatsioonide loogika vÔib olla mitmeastmeline ja konsolideerida andmeid mitmest teisest mudelist. NÀide mudelist, mis loob tellimuste vitriini (f_orders):
{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %}
with orders as (
select * from {{ ref('stg_orders') }}
),
order_payments as (
select * from {{ ref('order_payments') }}
),
final as (
select
orders.order_id,
orders.customer_id,
orders.order_date,
orders.status,
{% for payment_method in payment_methods -%}
order_payments.{{payment_method}}_amount,
{% endfor -%}
order_payments.total_amount as amount
from orders
left join order_payments using (order_id)
)
select * from final
Mida huvitavat me siin nÀha saame?
Esiteks: Kasutatakse CTE-d (Common Table Expressions) â koodi korraldamiseks ja mĂ”istmiseks, mis sisaldab palju transformatsioone ja Ă€riloogikat
Teiseks: Mudeli kood on SQL-i ja (mallimise keel) segu.
NĂ€ites kasutatakse tsĂŒklit for iga maksemeetodi summa kujundamiseks, nagu on vĂ€ljendatud set. Kasutatakse ka funktsiooni ref â vĂ”imalust viidata koodis teistele mudelitele:
- Kompileerimise ajal ref muutub see sihtmÀrgiks tabelile vÔi vaatele Andmehoidlas
- ref lubab sÔltuvuste graafiku koostamine mudelitest
Just lisab DBT-le peaaegu piiramatud vÔimalused. KÔige sagedamini kasutatavad neist on:
- If/else laused â haruoperatorid
- For tsĂŒklid â tsĂŒklid
- Muudatused â muutujad
- Makro â makrode loomine
Materjaliseerimine: Tabel, Vaade, Inkremetne
Materjaliseerimise strateegia â lĂ€henemine, mille kohaselt salvestatakse mudeli tulemusandmete kogum Ladustamisse.
PÔhilise kÀsitluse kohaselt see on:
- Tabel â fĂŒĂŒsiline tabel Ladustamises
- Vaade â esitus, virtuaalne tabel Ladustamises
On olemas ka keerukamaid materjaliseerimise strateegiaid:
- Inkremetne â inkremetne laadimine (suured faktitabelid); uued read lisatakse, muudetud â uuendatakse, kustutatud â eemaldatakseÂ
- Ephemeral â mudelit ei materjaliseerita otse, vaid see osaleb CTE-na teistes mudelites
- KĂ€ideldavad muud strateegiad, mida saate ise lisada
Lisaks materjaliseerimise strateegiatele avanevad vÔimalused optimeerimiseks konkreetsete Ladustamiste jaoks, nÀiteks:
- Snowflake: Ajutised tabelid, Ăhinemise kĂ€itumine, Tabeli grupeerimine, Ăiguste kopeerimine, Turvalised vaated
- Redshift: Distkey, Sortkey (vahelduv, komposiit), Hiline sidumise vaated
- BigQuery: Tabeli partitsioneerimine ja grupeerimine, Ăhinemise kĂ€itumine, KMS-krĂŒpteerimine, Sildid ja MĂ€rgid
- Spark: Failivorming (parquet, csv, json, orc, delta), partition_by, clustered_by, buckets, incremental_strategy
Hetkel toetatakse jÀrgmisi salvestusvorme:
- Postgres
- Redshift
- BigQuery
- Snowflake
- Presto (osaliselt)
- Spark (osaliselt)
- Microsoft SQL Server (kogukonna adapter)
Parandame meie mudelit:
- Teeme selle tÀiendamise inkrementaalseks (Incremental)
- Lisame segmentimise ja sortimise vÔtmed Redshiftile
-- Mudeli konfiguratsioon:Â
-- Inkrementaalne tÀitmine, unikaalne vÔti rekordite uuendamiseks (unique_key)
-- Segmentimise vÔti (dist), sorteerimise vÔti (sort)
{{
config(
materialized='incremental',
unique_key='order_id',
dist="customer_id",
sort="order_date"
)
}}
{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %}
with orders as (
select * from {{ ref('stg_orders') }}
where 1=1
{% if is_incremental() -%}
-- See filter rakendatakse ainult inkrementaalse kÀivitamise jaoks
and order_date >= (select max(order_date) from {{ this }})
{%- endif %}
),
order_payments as (
select * from {{ ref('order_payments') }}
),
final as (
select
orders.order_id,
orders.customer_id,
orders.order_date,
orders.status,
{% for payment_method in payment_methods -%}
order_payments.{{payment_method}}_amount,
{% endfor -%}
order_payments.total_amount as amount
from orders
left join order_payments using (order_id)
)
select * from final
Mudelite sÔltuvuste graafik
See on ka sĂ”ltuvuste puu. Samuti DAG (Suunatud AkeetsĂŒkkel Graaf).
DBT ehitab graafi projekti kÔigi mudelite konfiguratsiooni pÔhjal, tÀpsemalt mudelites olevate ref() viidete kaudu teistele mudelitele. Graafi olemasolu vÔimaldab teha jÀrgmist:
- Mudelite kÀitamine Ôiges jÀrjekorras
- Data warehouse'ide loomise paralleelne tÀitmine
- Mitte mingisuguse alagraafi kĂ€itamineÂ
Graafi visualiseerimise nÀide:

Iga graafi sÔlm on mudel, graafi servad mÀÀratakse ref vÀljendiga.
Andmete kvaliteet ja dokumentatsioon
Lisaks mudelite loomisele vĂ”imaldab DBT testida rida hĂŒpoteese (assertions) andmestiku tulemuste kohta, nagu nĂ€iteks:
- Not Null
- Unikaalne
- Viidete terviklikkus (nÀiteks customer_id tabelis orders peab vastama id-le tabelis customers)
- Sobivuse kontroll lubatud vÀÀrtuste loendiga
VĂ”imalik on lisada oma teste (kohandatud andmete testid), nĂ€iteks % mĂŒĂŒgitulu kĂ”rvalekalded eelmise pĂ€eva, nĂ€dala vĂ”i kuu kohta. Iga hĂŒpotees, mis on sĂ”nastatud SQL-pĂ€ringuna, vĂ”ib muutuda testiks.
Nii saab Reservoiri vitriinides tuvastada soovimatud kÔrvalekalded ja andmete vead.
Mis puutub dokumenteerimisse, siis DBT pakub mehhanisme metateabe ja kommentaaride lisamiseks, versioonide haldamiseks ning levitamiseks mudelite ja isegi atribuutide tasandil.Â
Nii nÀeb vÀlja testide ja dokumentatsiooni lisamine konfiguratsioonifaili tasandil:
 - name: fct_orders
description: See tabel sisaldab pÔhiteavet tellimuste kohta, samuti mÔningaid maksete pÔhjal saadud faktilisi andmeid
columns:
- name: order_id
tests:
- unique # vÀÀrtuste unikaalsuse kontroll
- not_null # null-i olemasolu kontroll
description: See on unikaalne identifikaator tellimuse jaoks
- name: customer_id
description: VÀlisvÔti klientide tabelisse
tests:
- not_null
- relationships: # viidete terviklikkuse kontroll
to: ref('dim_customers')
field: customer_id
- name: order_date
description: KuupÀev (UTC), millal tellimus tehti
- name: status
description: '{{ doc("orders_status") }}'
tests:
- accepted_values: # lubatud vÀÀrtuste kontroll
values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']
Nii nÀeb see dokumentatsioon vÀlja juba genereeritud veebilehel:

Makrode ja moodulite
DBT eesmÀrk ei ole mitte lihtsalt SQL-skriptide kogum, vaid pakkuda kasutajatele vÔimsaid ja mitmekesiseid vahendeid oma transformatsioonide loomiseks ja nende moodulite jagamiseks.
Makrosid kasutatakse konstruktsioonide ja vĂ€ljendite kogumina, mida saab kutsuda funktsioonidena mudelites. Makrosid saab uuesti kasutada SQL-i mudelite ja projektide vahel vastavalt inseneriprinsipile DRY (Ăra Korda Iseennast).
Makro nÀide:
{% macro rename_category(column_name) %}
case
when {{ column_name }} ilike '%osx%' then 'osx'
when {{ column_name }} ilike '%android%' then 'android'
when {{ column_name }} ilike '%ios%' then 'ios'
else 'other'
end as renamed_product
{% endmacro %}
Ja selle kasutamine:
{% set column_name = 'product' %}
select
product,
{{ rename_category(column_name) }} -- makro kutsumine
from my_table
DBT tuleb koos pakettide halduriga (packages), mis vÔimaldab kasutajatel avaldada ja uuesti kasutada eraldi mooduleid ja makrosid.
See tÀhendab, et on vÔimalik laadida ja kasutada selliseid teeke nagu:
- : Date/Time töötlemine, asendusbitaendid, skeemi testid, Pivot/Unpivot ja muud
- Valmis mallid selliste teenuste jaoks nagu ja Â
- Teegid konkreetsete andmehoidlate jaoks, nĂ€iteks Â
- â DBT töö logimise moodul
Kogu paketide loetelu on saadaval .
Veel rohkem vÔimalusi
Siin kirjeldan mÔningaid teisi huvitavaid omadusi ja rakendusi, mida mina ja minu meeskond kasutame Andmete Lao loomisel .
KĂ€itusvĂ€ljade jagamine DEV â TEST â PROD
Isegi ĂŒhe DWH klastri sees (erinevate skeemide raames). NĂ€iteks jĂ€rgmise lause abil:
with source as (
Â
   select * from {{ source('salesforce', 'users') }}
   where 1=1
   {%- if target.name in ['dev', 'test', 'ci'] -%}          Â
       where timestamp >= dateadd(day, -3, current_date)  Â
   {%- endif -%}
Â
)
See kood ĂŒtleb sĂ”na-sĂ”nalt: keskkondadele dev, test, ci vĂ”ta andmed ainult viimase 3 pĂ€eva jooksul ja mitte rohkem. See tĂ€hendab, et need keskkonnad pÀÀsevad palju kiiremini ja vajavad vĂ€hem ressursse. KĂ€ivitamisel keskkonnas prod filtreerimise tingimus jĂ€etakse tĂ€helepanuta.
Alternatiivse veergude kodeerimise materialiseerimine
Redshift on veergudega andmebaas, mis vÔimaldab mÀÀrata iga veeru jaoks andmete tihendamise algoritme. Optimaalsete algoritmide valik vÔib vÀhendada kettaruumi kasutust 20-50%.
Makro tÀidab ANALYZE COMPRESSION kÀsku, loob uue tabeli soovitatud veergude kodeerimisalgoritmidega, kasutades mÀÀratud segmentimise (dist_key) ja sortimise (sort_key) vÔtmeid, edastab andmed sinna ja vajadusel kustutab vana koopia.
Makro allkiri:
{{ compress_table(schema, table,
drop_backup=False,
comprows=none|Integer,
sort_style=none|compound|interleaved,
sort_keys=none|List,
dist_style=none|all|even,
dist_key=none|String) }}
Mudelite kÀivitamise logimine
Iga mudeli tÀitmise juurde saab lisada hook'e, mis kÀivitatakse enne mudeli kÀivitamist vÔi kohe pÀrast mudeli loomise lÔppu:
   pre-hook: "{{ logging.log_model_start_event() }}"
post-hook: "{{ logging.log_model_end_event() }}"
Logimismoodul vĂ”imaldab salvestada kĂ”ik vajalikud metaandmed eraldi tabelisse, mille pĂ”hjal on hiljem vĂ”imalik teostada auditeid ja analĂŒĂŒsida probleemikohti.
Nii nÀeb vÀlja Lookeris logimise andmetel pÔhinev juhtpaneel:

Laokogumiku hoolduse automatiseerimine
Kui kasutate mÔningaid laohalduse funktsionaalsuse laiendusi, nagu UDF (kasutaja mÀÀratud funktsioonid), on nende funktsioonide versiooniuuendamine, ligipÀÀsu haldamine ja uute versioonide automaatne rakendamine DBT-s vÀga mugav.
Kasutame UDF-e Pythonis, et arvutada rÀsivÀÀrtusi, meiliaadresside domeene ja dekodeerida bitmask-e.
Mikro nÀide, mis loob UDF-i igas tÀitevkeskkonnas (dev, test, prod):
{% macro create_udf() -%}
{% set sql %}
CREATE OR REPLACE FUNCTION {{ target.schema }}.f_sha256(mes "varchar")
RETURNS varchar
LANGUAGE plpythonu
STABLE
AS $$
import hashlib
return hashlib.sha256(mes).hexdigest()
$$
;
{% endset %}
{% set table = run_query(sql) %}
{%- endmacro %}
Wheelys kasutame Amazon Redshifti, mis pĂ”hineb PostgreSQL-il. Redshifti jaoks on oluline regulaarselt koguda statistikat tabelite kohta ja vabastada ketas â vastavad kĂ€sud ANALYZE ja VACUUM.
Selleks kÀivitatakse iga öö redshift_maintenance makro sisalduvad kÀsud:
{% macro redshift_maintenance() %}
{% set vacuumable_tables=run_query(vacuumable_tables_sql) %}
{% for row in vacuumable_tables %}
{% set message_prefix=loop.index ~ " of " ~ loop.length %}
{%- set relation_to_vacuum = adapter.get_relation(
database=row['table_database'],
schema=row['table_schema'],
identifier=row['table_name']
) -%}
{% do run_query("commit") %}
{% if relation_to_vacuum %}
{% set start=modules.datetime.datetime.now() %}
{{ dbt_utils.log_info(message_prefix ~ " Vacuuming " ~ relation_to_vacuum) }}
{% do run_query("VACUUM " ~ relation_to_vacuum ~ " BOOST") %}
{{ dbt_utils.log_info(message_prefix ~ " Analyzing " ~ relation_to_vacuum) }}
{% do run_query("ANALYZE " ~ relation_to_vacuum) %}
{% set end=modules.datetime.datetime.now() %}
{% set total_seconds = (end - start).total_seconds() | round(2) %}
{{ dbt_utils.log_info(message_prefix ~ " Finished " ~ relation_to_vacuum ~ " in " ~ total_seconds ~ "s") }}
{% else %}
{{ dbt_utils.log_info(message_prefix ~ ' Skipping relation "' ~ row.values() | join ('"."') ~ '" as it does not exist') }}
{% endif %}
{% endfor %}
{% endmacro %}
DBT Cloud
DBT teenusena (Halletud teenus) kasutamise vÔimalus. Komplekti kuuluvad:
- Web IDE projektide ja mudelite arendamiseks
- Tööde konfigureerimine ja ajastamine
- Lihtne ja mugav juurdepÀÀs logidele
- Teie projekti dokumentatsiooni veebisait
- CI (Continuous Integration) ĂŒhendamine

KokkuvÔte
Andmete ladustamise (DWH) valmistamine ja kasutamine on sama meeldiv ja kasulik kui smuuti joomine. DBT koosneb Jinjast, kohandatud laiendustest (moodulitest), kompilaatorist, tĂ€itmisajamust (executor) ja pakihaldurist. Kogudes need elemendid ĂŒhte, saate tĂ€iusliku töökorralduse oma andmete ladustamiseks. TĂ€napĂ€eval on raske leida paremat viisi DWH-s transformatsioonide haldamiseks.
DBT arendajate jÀrgitud veendumused on jÀrgmised:
- Kood, mitte GUI, on parim abstraktsioon keerulise analĂŒĂŒtilise loogika vĂ€ljendamiseks
- Andmetega töötamine peaks kohandama parimaid tarkvaraarenduse (Software Engineering) praktikaid
- KÔige olulisem andmete töötlemise infrastruktuur peaks olema kontrollitud kasutajate kogukonna poolt avatud lÀhtekoodiga tarkvarana
- Mitte ainult analĂŒĂŒsitööriistad, vaid ka kood muutub jĂ€rjest enam avatud lĂ€htekoodiga kogukonna varaks
Needus uskumused on loonud toote, mida tĂ€na kasutavad ĂŒle 850 ettevĂ”tte ja need on aluseks paljudele huvitavatele laiendustele, mis tulevikus luuakse.
Neile, kes on huvitatud, on olemas video salvestus avatud loengust, mille ma viisid lĂ€bi mĂ”ned kuud tagasi OTUSi avatud loengute raames â .
Lisaks DBT-le ja Andmete Ladustamisele viib OTUSi Data Engineer kursuse raames mina ja mu kolleegid lÀbi loenguid mitmetes muudest aktuaalsetest ja kaasaegsetest teemadest:
- Suuri Andmeid rakenduste arhitektuuri kontseptsioonid
- Praktika Sparkiga ja Spark Streaminguga
- Andmeallikate laadimise meetodite ja vahendite uurimine
- AnalĂŒĂŒtiliste vitriinide ehitamine DWH-s
- NoSQL kontseptsioonid: HBase, Cassandra, ElasticSearch
- JĂ€lgimise ja orkestreerimise korraldamise pĂ”himĂ”ttedÂ
- LÔppprojekt: kogume kÔik oskused kokku mentorite toetusel
Lingid:
- â Ametlik dokumentatsioon
- â DBT ĂŒhe autori ĂŒlevaate artikkelÂ
- â YouTube, OTUSi avatud loengu salvestus
- â JĂ€rgmine avatud loeng 15. mai 2020
- â OTUS
- â Pilk tulevikku andmete ja analĂŒĂŒsi töötamises
- â AnalĂŒĂŒsi evolutsioon ja avatud lĂ€htekoodi mĂ”ju
- â CI pĂ”himĂ”tted DBT kasutamisel
- â Praktika, Samm-sammult juhised iseseisvaks tööks
- â Github, Ă”ppeprojekti kood
Allikas: habr.com

