
Millised pÔhimÔtted on ideaalne Andmesaal ehitatud?
Fookus Ă€rivÀÀrtusel ja analĂŒĂŒtikal ilma boilerplate koodita. DWH haldamine koodibaasina: versioonihaldus, ĂŒlevaatus, automaatne testimine ja CI. Moodulsus, laiendatavus, avatud lĂ€htekood ja kogukond. SĂ”bralik kasutajate dokumentatsioon ja sĂ”ltuvuse visualiseerimine (Data Lineage).
KĂŒsimuses selle ja DBT rollist Big Data & Analytics ökosĂŒsteemis â tere tulemast edasi lugema.
Tere kÔigile
Olen Artiom Koster. Juba ĂŒle 5 aasta töötan andmesaalidega, tehes ETL/ELT projekte ning tegeledes andmete analĂŒĂŒsiga ja visualiseerimisega. Praegu töötan , Ă”petan OTUS'is kursusel , ja tĂ€na tahan jagada teiega artiklit, mille kirjutasin enne uue kursuse komplekti algust.
LĂŒhike ĂŒlevaade
DBT raamistiku olemus on kĂ”ik selle T kohta ELT akronĂŒĂŒmis (Extract â Transform â Load).
Selliste produktiivsete ja skaleeritavate analĂŒĂŒsibaaside nagu BigQuery, Redshift, Snowflake ilmumisega kaotas igasugune mĂ”te teha transformatsioone vĂ€ljaspool Andmesaldo.Â
DBT ei laadita andmeid allikatest, kuid pakub tohutuid vÔimalusi juba laaditud andmetega töötamiseks Andmesaalis (Internal vÔi External Storage).

DBT pÔhieesmÀrk on vÔtta kood, kompileerida see SQL-ks ja kÀivitada kÀsud Ôiges jÀrjekorras Andmesaalis.
DBT projekti struktuur
Projekt koosneb vaid kahest tĂŒĂŒpi kaustadest ja failidest:
- Mudel (.sql) â transformatsiooni ĂŒksus, vĂ€ljendatud SELECT-pĂ€ringuga
- Konfiguratsioonifail (.yml) â parameetrid, seaded, testid, dokumentatsioon
Alustasime, et töö toimub jÀrgmiselt:
- Kasutaja valmistab mudelite koodi ette mis tahes mugavas IDE-s
- CLI abil kÀivitatakse mudelid, DBT kompileerib mudelite koodi SQL-iks
- Kompileeritud SQL-kood tÀidetakse Andmesaalis mÀÀratud jÀrjekorras (graaf)
Siit vÔiks nÀha CLI-s kÀivitust:

KÔik on SELECT
See on Data Build Tool raamistikku tapvate omaduste ĂŒks. TeisisĂ”nu, DBT abstrak Compute kĂ”ik kood, mis on seotud teie pĂ€ringute materialiseerimisega Andmesaalis (variatsioonid kĂ€skudest CREATE, INSERT, UPDATE, DELETE ALTER, GRANT, âŠ).
Iga mudel sisaldab ĂŒhe SELECT-pĂ€ringu kirjutamist, mis mÀÀrab tulemuseks oleva andmeseti.
Selle puhul vÔib teisendusloogika olla mitmetasandiline ja konsolideerida andmeid mitmest muust mudelist. NÀide mudelist, mis loob tellimuste vÀljundi (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: Kasutatud on CTE-sid (Common Table Expressions) â koodi korraldamiseks ja mĂ”istmiseks, mis sisaldab palju teisendusi ja Ă€riloogikat.
Teiseks: Mudeli kood on segu SQL-ist ja (ĆĄabloonikeel).
NĂ€ites on kasutatud tsĂŒklit for iga makseviisi summa kuvamiseks, mis on mÀÀratletud vĂ€ljendis set. Samuti kasutatakse funktsiooni ref â vĂ”imalust viidata koodis teistele mudelitele:
- Kompileerimise ajal ref muudetakse see sihituspunktiks, mis viitab tabelile vÔi vaatele Andmehoidlas
- ref vÔimaldab luua mudelite sÔltuvuste graafi.
Just see lisab DBT-le peaaegu piiramatu vÔimekuse. KÔige sagedamini kasutatavad neist on:
- If / else laused â haruoperatsioonid
- For tsĂŒklid â silmustamine
- Muutujad â muutujad
- Makro â makrode loomine
Materialiseerimine: Table, View, Incremental
Materialiseerimisstrateegia â lĂ€henemine, mille kohaselt salvestatakse mudeli tulemusandmestik Andmehoidlas.
PÔhjalikus vaates on see:
- Table â fĂŒĂŒsiline tabel Andmehoidlas
- View â vaade, virtuaalne tabel Andmehoidlas
On ka keerukamaid materialiseerimise strateegiaid:
- Incremental â inkrementaalne laadimine (suurte faktite tabelite); uued read lisatakse, muudetud â uuendatakse, kustutatud â eemaldatakse.Â
- Ephemeral â mudel ei materialiseeru otse, kuid osaleb kui CTE teistes mudelites.
- KÔik muud strateegiad, mida vÔite ise lisada.
Lisaks materialiseerimisstrateegiatele avanevad vÔimalused optimeerimiseks konkreetsete Andmehoidlate jaoks, nÀiteks:
- Snowflake: Transient tables, Merge behavior, Table clustering, Copying grants, Secure views
- Redshift: Distkey, Sortkey (interleaved, compound), Late Binding Views
- BigQuery: Table partitioning & clustering, Merge behavior, KMS Encryption, Labels & Tags
- Spark: Failivormaat (parquet, csv, json, orc, delta), partition_by, clustered_by, buckets, incremental_strategy
Praegu toetatakse jÀrgmisi ladustamisi:
- Postgres
- Redshift
- BigQuery
- Snowflake
- Presto (osaliselt)
- Spark (osaliselt)
- Microsoft SQL Server (kogukonna adapter)
Laske meil oma mudelit tÀiustada:
- Teeme selle tÀiendamise inkrementselt (Incremental)
- Lisame Redshifti segmenteerimise ja sortimise vÔtmed
-- Mudeli konfiguratsioon:
-- Inkrementaalne tÀiendamine, unikaalne vÔti salvestuste uuendamiseks (unique_key)
-- Segmenteerimise vÔti (dist), sortimise 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 rakendub ainult inkrementaalsete kÀivituste 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Ôltuvusgraafik
Sama mis sĂ”ltuvuspuu. Sama mis DAG (Directed Acyclic Graph â suunatud tsĂŒkliline graaf).
DBT loob graafi kÔikide projekti mudelite konfiguratsiooni pÔhjal, tÀpsemalt mudelite sees oleva ref() viidatud teistele mudelitele. Graafi olemasolu vÔimaldab jÀrgmisi asju:
- Mudelite kÀitamine Ôigetes jÀrjestustes
- Kuvandite loomise paralleliseerimine
- Suvalise alagraafi kĂ€itamineÂ
Graafi visualiseerimise nÀide:

Iga graafi sÔlm on mudel, graafi servad mÀÀratakse ref'i vÀljendiga.
Andmete kvaliteet ja Dokumentatsioon
Lisaks mudelite koostamisele vÔimaldab DBT testida rea oletusi (assertions) tulemuste andmestiku kohta, nagu nÀiteks:
- Not Null
- Ainulaadne
- Reference Integrity â viidatud terviklikkus (nt customer_id tabelis orders peab vastama id-le tabelis customers)
- Vastavus lubatud vÀÀrtuste loetelule
VÔimalik on lisada oma teste (custom data tests), nÀiteks % tulude kÔrvalekalle vÔrreldes nÀitajatega pÀev, nÀdal, kuu tagasi. Iga oletus, mis on sÔnastatud SQL-pÀringuna, vÔib saada testiks.
Nii saab tuvastada ladustamissĂŒsteemide kuvandites soovimatuid kĂ”rvalekaldeid ja vigu andmetes.
Mis dokumenteerimise osas pakub DBT mehhanisme metaandmete ja kommentaaride lisamiseks, versioonide haldamiseks ja levitamiseks mudelite ja isegi atribuutide tasandil.Â
Siin on, kuidas nÀeb vÀlja testide ja dokumentatsiooni lisamine konfiguratsioonifaili tasandil:
 - name: fct_orders
description: See tabel sisaldab pÔhiteavet tellimuste kohta, samuti teatud tuletatud fakte maksete pÔhjal
columns:
- name: order_id
tests:
- unique # vÀÀrtuste unikaalsuse testimine
- not_null # nulli olemasolu testimine
description: See on tellimuse unikaalne identifikaator
- name: customer_id
description: Viidatud vÀlisvÔti klientide tabelisse
tests:
- not_null
- relationships: # viidatud terviklikkuse testimine
to: ref('dim_customers')
field: customer_id
- name: order_date
description: Aeg (UTC), millal tellimus tehti
- name: status
description: '{{ doc("orders_status") }}'
tests:
- accepted_values: # lubatud vÀÀrtuste testimine
values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']
Nii nÀeb see dokumentatsioon juba genereeritud veebisaidil vÀlja:

Makrod ja moodulid
DBT eesmÀrk ei ole mitte ainult SQL-skriptide kogumi loomine, vaid ka kasutajatele vÔimsate ja funktsionaalsete vahendite pakkumine oma transformatsioonide loomiseks ja nende moodulite levitamiseks.
Makrod on konstruktsioonide ja vĂ€ljendite kogumid, mida saab mudelites funktsioonidena kutsuda. Makrod vĂ”imaldavad SQL-i taaskasutamist mudelite ja projektide vahel vastavalt inseneritehnika pĂ”himĂ”ttele DRY (Ăra Korrake End).
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 kutse
from my_table
DBT tarnitakse koos paketihalduriga (packages), mis vÔimaldab kasutajatel eraldi mooduleid ja makrosid avaldada ning taaskasutada.
See tÀhendab vÔimalust laadida ja kasutada selliseid teeke nagu:
- : töötlus Date/Time, Surrogate Keys, skeemide testimine, Pivot/Unpivot ja muud
- Valmis vitriinide mallid selliste teenuste jaoks nagu ja Â
- Spetsiifiliste andmehoidlate teegid, nĂ€iteks Â
- â DBT töö logimise moodul
TĂ€ispakettide nimekirjaga saab tutvuda .
Veelgi rohkem vÔimalusi
Siin kirjeldan mÔningaid teisi huvitavaid omadusi ja teostusi, mida mina ja minu meeskond kasutame Andmete Ladu ehitamiseks .
KĂ€ivituskeskkondade jagamine DEV â TEST â PROD
Isegi ĂŒhe DWH klastri sees (erinevate skeemide raames). NĂ€iteks jĂ€rgmise vĂ€ljendiga:
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 otseses mĂ”ttes: vĂ”tke andmed ainult viimase 3 pĂ€eva jooksul ja mitte rohkem. See tĂ€hendab, et töö kĂ€ivitamine neis keskkondades on palju kiirem ja nĂ”uab vĂ€hem ressursse. KĂ€ivitamisel keskkonnas dev, test, ci filtreerimise tingimus jĂ€etakse kĂ”rvale. prod Materjaliseerimine alternatiivsete veergude kodeerimisega
Redshift on veergude andmebaas, mis vĂ”imaldab mÀÀrata andmete tihendamise algoritme iga ĂŒksiku veeru jaoks. Optimaalsed algoritmide valikud vĂ”ivad vĂ€hendada ketta vajalikku ruumi 20-50%.
Makro
redshift.compress_table 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Àivituste logimine
Iga mudeli tÀitmisele saab riputada konksud (hooks), mis tÀidetakse enne kÀivitamist vÔi kohe pÀrast mudeli loomise lÔpetamist:
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 alusel saab hiljem teostada auditi ja analĂŒĂŒsida probleemseid kohti (bottlenecks).
NÀiteks nÀeb logimist, kuidas logimistabel Lookeris vÀlja nÀeb:
Andmete ladustamise hoolduse automatiseerimine

Kui kasutate Andmete Ladustamiseks mÔnda funktsionaalsuse laiendust, nÀiteks UDF (Kasutaja MÀÀratletud Funktsioonid), on nende funktsioonide versioonide haldamine, juurdepÀÀsude juhtimine ja automaatne uute versioonide juurutamine vÀga mugav DBT-s.
Kui kasutate oma andmehoidla funktsionaalsuse laiendamiseks mÔningaid funktsioone, nagu UDF (kasutaja mÀÀratletud funktsioonid), on nende funktsioonide versioonihaldus, juurdepÀÀsuhaldus ja uute vÀljaannete automatiseeritud juurutamine DBT-s vÀga mugav.
Me kasutame Pythonis UDF-i, et arvutada rÀsi vÀÀrtusi, domeene e-posti aadressidelt, dekodeerida bitimaskid (bitmask).
Makro nÀide, mis loob UDF-i igas tÀitmis keskkonnas (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 kettaruumi - vastavalt kÀskude ANALYZE ja VACUUM.
Selleks tÀidetakse igal ööl kÀsklused makrost redshift_maintenance:
{% 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
On vÔimalus kasutada DBT-t teenusena (Managed Service). Komplektis:
- Web IDE projektide ja mudelite arendamiseks
- Tööde konfigureerimine ja ajastamine
- Lihtne ja mugav juurdepÀÀs logidele
- Veebisait teie projekti dokumentatsiooniga
- CI (Continuous Integration) ĂŒhendamine

KokkuvÔte
DWH valmistamine ja kasutamine muutub sama meeldivaks ja kasulikuks nagu smuuti joomine. DBT koosneb Jinjast, kasutaja laienditest (moodulitest), kompilaatorist, kÀitistest ja paketihaldurist. Kui tuua need elemendid kokku, saate tÀieliku töökeskkonna oma Andmete Ladustamiseks. Vaevalt on tÀna olemas parem viis DWH-s transformatsioonide haldamiseks.
Usun, et DBT arendajad jÀrgivad selliseid veendumusi:
- Kood, mitte graafiline kasutajaliides, on parim abstraktsioon keerulise analĂŒĂŒsiloogika vĂ€ljendamiseks
- Andmetega töötamine peaks kohandama parimaid tarkvaraarenduse praktikaid
- Oluline andmeinfrastruktuur peaks olema kontrollitav avatud lÀhtekoodiga tarkvara kasutajate kogukonna poolt
- Kuna analĂŒĂŒtika tööriistad, muutub ka kood ĂŒha enam avatud lĂ€htekoodiga kogukonna pĂ€randiks
Need pĂ”hiveendumused on tootnud toote, mida tĂ€na kasutab ĂŒle 850 ettevĂ”tte ning nad moodustavad aluse paljudele tulevastele huvitavatele laiendustele.
Neile, kes on huvitatud, on saadaval videorecording avatud tunnist, mille ma mĂ”ned kuud tagasi lĂ€bi viisin OTUS-i avatud tunni raames â .
Peale DBT ja Andmehoidlate, Ôpetame OTUS-i Data Engineer kursusel mitmeid teisi aktuaalseid ja kaasaegseid teemasid:
- Suured Andmed rakenduste arhitektuurilised kontseptsioonid
- Praktika Sparkiga ja Spark Streaminguga
- Andmeallikate laadimise meetodite ja tööriistade uurimine
- AnalĂŒĂŒtiliste vitriinide ehitamine DWH-s
- NoSQL kontseptsioonid: HBase, Cassandra, ElasticSearch
- Monitooringu ja orkestreerimise korraldamise pĂ”himĂ”ttedÂ
- LĂ”ppprojekt: ĂŒhendame kĂ”ik oskused juhendaja toetava toe all
Lingid:
- â Ametlik dokumentatsioon
- â Ălevaade ĂŒhel DBT autorilÂ
- â YouTube, OTUS avatud tunni salvestus
- â JĂ€rgmine avatud tund 15. mai 2020
- â OTUS
- â Vaade andmete ja analĂŒĂŒsi tulevikku
- â AnalĂŒĂŒsi ja avatud lĂ€htekoodi mĂ”ju evolutsioon
- â CI loomise pĂ”himĂ”tted DBT kasutades
- â Praktika, Samm-sammult juhised iseseisvaks tööks
- â Github, Ă”ppeprojekti kood
Allikas: habr.com

