dbt | 10 tips til deg som vil kome i gong
12.02.2022 | 10 min lesetidKategori: Data Engineering | Emneknagg: #dbt
1. Følg beste praksis, og spør forumet når du er i tvil
Det viktigaste ein gjer er å bestemme seg for å bruke dbt. Det nest viktigaste ein gjer er å starte på rett fot ved å lese seg opp på kva som er beste praksis. dbt Labs, selskapet bak dbt, er heldigvis særs ivrige på å dele av sine kunnskap, og har tilgjengeleggjort ei solid liste med tips og triks for korleis ein burde gå fram: dbt best practices
I tillegg til å vere rimelig flinke til å dokumentere på nett har og dbt, i kraft av å vere både mykje brukt og open source, eit levande community som finnes på slack. Her finnes fora for alle mogleg behov, og ein kan rekne med å raskt få respons frå utviklarar av produktet eller frå erfarne brukarar.
2. Definer utviklingsstandarden
Eit naturleg neste steg, som er så viktig at det blir nemnt her sjølv om det og finnes via punktet over, er å definere utviklingsstandarden før ein i det heile tatt byrjar på ein dbt-implementasjon. Dette er særleg viktig i større team, men og svært nyttig når ein berre er ein utviklar då dette tvinger fram ein del val som sikrer konsistens i det som blir gjort.
Det er ikkje heilt uvanleg at ting utviklar seg over tid, nye utviklarar kjem til, og det blir tatt i bruk alternative måtar å gjere ting på. Tillet ein dette vil ein fort ende opp med å ha eit prosjekt fullt av spagetti-arkitektur.
Ved å først tenkje gjennom og dokumentere ein utviklingsstandard som skal følgjast så blir det enklare å utvikle og gjere kodesjekk, samt at det vert enklare for nye utviklarar å kome inn i prosjektet. Når standarden blir konkret på dette viset blir det og enklare å revurdere den jamnleg etterkvart som ein gjer seg nye erfaringar. NB: hugs punkt 10 om refaktorering når standarden blir endra.
Ein god plass å byrje for å lage sin eigen utviklingsstandard er å ta utgangspunkt i den som dbt har gjort tilgjengeleg: dbt style guide
I tillegg er The Zen of Python evig aktuell.
3. Design lagdelingen i arkitekturen tidleg
På same måte som at ein burde ha standarden klar tidleg, burde ein og ha ein tydeleg plan for dei ulike laga ein skal ha i arkitekturen. Då er det ikkje kun snakk om kor mange og korleis dei skal namngis, men det kanskje aller viktigaste er å bestemme kva rolle dei skal spele og korleis laga skal interagere.
Uavhengig av antalet lag ein ender opp med er det, som dbt anbefaler, ein veldig god praksis å la det første laget vere eit reint standardiseringslag som er 1:1 mot kjeldetabellen. På denne måten sørgjer ein for å endre namn, handtere datakvalitet og datatypar samt andre enkle operasjonar på ein felles plass, og som alle etterfølgjande modellar kan dra nytte av.
Utover dette kan det vere ein god praksis å ha som basisregel at kvart lag i all hovedsak skal hente data frå det foregåande laget, då dette sørgjer for at ein slepp uklare avhengigheter på kryss og tvers innad i eit lag.
4. Ha ein tydeleg utviklingsprosess med kodesjekk
Når man først har kommet i gang med utviklingen, og har utviklingsstandarden og arkitekturen på plass, må man så sette rammene og prosessene for å sørge for at alt blir overholdt. Her kan man gjøre mange enkle men effektive tiltak. Når det komme til nye utviklere burde man allerede ha dokumentert ned det man har landet i stegene over, slik at det er enkelt å lese seg opp på. I tillegg er det en god øvelse å utøve parprogrammering i en viss grad i starten.
Utover dette burde man sette prosessen i system gjennom å definere pull request-templates og sette opp branch policies som sørger for at det automatisk blir tilordnet en code reviewer når en pull request opprettes. CI/CD-prosesser vil også hjelpe på her.
5. Tenk alltid DRY
I motsetnad til meir tradisjonelle, grafiske ETL-verktøy, får ein gjennom eit kodebasert verktøy som dbt ein del moglegheiter til å gjere ting meir i henhald til klassisk beste praksis kjent frå programvareutvikling. DRY er eit særs viktig prinsipp her - don’t repeat yourself. Med andre ord, skal du løyse det same problemet fleire ganger, sørg for å bygge struktur og funksjonar som gjer at koden kan attbrukast, og at ein kun må vedlikehalde den ein stad.
I dbt er det (minst) tre ulike komponentar ein kan ta i bruk her:
- Utnytte lagdelinga: Ein effektiv lagdeling, der namneendring, bytte av datatypar og handtering av datakvalitet blir gjort tidleg og kun på ein stad gjer at alle etterfølgjande avhengigheter slepp å løyse det same problemet igjen og igjen.
- Makroer: Ein nøkkelkomponent i dbt er jinja. Her kan ein byggje macroar for å løyse eit spesifikt problem. Dette kan vere heilt enkle ting for å standardisere datatypekonvertering, filtrering eller nøkkelbygging, eller langt meir avanserte ting. Moglegheitene er (nesten) endelause, og for meir avanserte brukarar opner dette og opp for å overstyre innebygd funksjonalitet om ein har behov for det.
- Variabler: dbt har og god støtte for å definere variabler på ulike nivå som ein kan bruke i definisjon av modellar eller som del av macroar.
6. Bruk eit verktøy som poetry eller devcontainer for utvikling
Skal ein skalere utviklinga i dbt, gjerne med mange utviklarar fordelt på fleire team, er ein avhengig av at alle får opp utviklingsmiljøet raskt og effektivt, og at det fungerer heilt likt hos alle. I tillegg må ein og ha moglegheita til å gjere endringar på utviklingsmiljøet hos alle meir eller mindre samtidig ved behov, eksempelvis når dbt skal oppdaterast til ein ny versjon.
Det er fleire måtar å få til dette på, der ein god måte er å bruke poetry. Då definerer ein utviklingsmiljøet som ein del av dbt-repoet, og pakkebehandlaren poetry sørgjer for oppretting av eit virtuelt miljø og installasjon av alle dei same pakkane med rette versjonar.
Eit alternativt til dette er å bruke devcontainere. På same måte definerer ein utviklingsmiljøet som ein del av dbt-repoet, og docker sørgjer for at alle nødvendige komponentar blir installert heilt likt overalt.
I begge tilfelle blir utviklingsopplevelsen heilt lik som om ein skulle ha installert alt lokalt (i alle fall gitt at ein har nokolunde nok minne tilgjengeleg, for bruk av devcontainere kan bli tungkjørt).
7. Dokumenter og implementer testar samstundes med kodeimplementasjon
Det er fort gjort at dokumentasjon og testing blir nedprioritert når ein kjenner at tidsfristen nærmar seg og ein ennå har mykje som må gjerast. Men i dbt er det så enkelt å gjere begge delar at ein i realiteten ikkje har unnskyldningar for å ikkje gjere begge delar samstundes som ein skriv koden.
Eit raskt eksempel kan sjå ut som følgjer for tabellen eksempel
. Her er det definert både ein tabellbeskrivelse, ein kolonnebeskrivelse med innhenta datatype, samt to definerte testar for kolonna - at den skal vere unik og at den ikkje skal ha null-verdiar.
Og kva skal til for å oppnå dette? Skarve 9 linjer med tekst.
models:
- name: eksempel
description: Dette er et eksempel på en tabell
columns:
- name: kolonne_1
description: Dette er den første kolonnen i tabellen
tests:
- unique
- not_null
Når ein først har gjort dette så vil alt dukke opp i dbt dokumentasjonen, og om ein bruker funksjonen build så vil dbt først køyre modellen for å opprette den, og deretter køyre begge testane som er definert for å sjå om dei passerer. Ellers er det og mogleg å kun køyre testane med kallet dbt test.
Her er ei oversikt over innebygde testar i dbt. Men hugs at ein kan alltid kan definere sine eigne etter behov.
8. Utnytt at dbt gjer CI/CD enkelt
State
dbt har ei mengd funksjonar som gjer det eigna for CI/CD-prosessar, og det burde utnyttast.
Et veldig godt eksempel på dette er state. dbt har moglegheit til å lagre staten sin, det vil seie tilstanden kodebasen var i, etter ei køyring. Ved neste køyring kan ein så samanlikne kodebasen og velge å kun køyre det som er nytt eller endra sidan sist, I eksempelet under kan ein sjå dette, og her vil og alle etterfølgjande avhengigheter køyre (sjå +-en etter state:modified) - dette er ein ofte avhengig av ved deploy.
dbt run --select state:modified+ --full-refresh
Dette var kun eitt eksempel på bruken av dbt sin kommandolinjesyntaks, men den er svært fleksibel og det kan være ei nyttig øving å få eit intimt forhold til den.
Dokumentasjon
Ein annen moglegheit som ein gjerne kan nytte seg av er å bygge og deploye dokumentasjonen kva gong ein gjer ein deploy til eit anna miljø, slik at ein alltid har oppdatert dokumentasjon for miljøa sine. Det blir då ein enkel inngongsport for både utviklarar og analytikarar, som kan vere trygge på at det dei ser i dokumentasjonen samsvarer med det dei ser i databasen.
Å byggje dokumentasjonen er berre endå ein variant av kommandolinjemoglegheitene til dbt. Dei genererte filene kan så deployast til ønska lokasjon. Dette er berre ei statisk nettside, og kan dermed eksempelvis leverast frå ein data lake.
9. Sjå på det som ei modningsreise
Det kan i starten verke overveldande å ta inn over seg alt ein burde tenke på i forbindelse med eit dbt-prosjekt, men det er det ingen grunn til. Ting går sjeldant veldig feil i dbt - ein endrer aldri på kjeldedataene, og ei full rekøyring av alle modellE er berre ein dbt run --full-refresh
unna. Det betyr at ein trygt kan sjå på det som ei modningsreise der ein byggjer på litt etter litt, og etter kvart som ein modnast kan ein ta i bruk meir avansert funksjonalitet.
Macroar og CI/CD-prosessar gjer livet enklare, men ein kan fint leve utan det. Start enkelt, løys dei første behova, og ta det derifrå.
10. Refaktorer ofte
Og eit siste men svært viktig tips til slutt - refaktorer ofte! Som nemnt vil ting utvikle seg over tid, ein modnast og gjer seg nye erfaringar, og finn smartare måtar å gjere ting på. Det er sånn det skal vere.
Men når dette skjer så må ein ikkje gå i fella som er å byrje å gjere ting på ein ny måte utan å samstundes endre det gamle - eller minimum leggje ein plan for når det skal gjerast. Det er oppskrifta på å pådra seg teknisk gjeld og ein framtidig spagetti-arkitektur.
dbt gjer refaktorering svært enkelt. Det er bare snakk om vanlege tekstfiler, som dermed kan endrast fort. Ønskjer ein å gjere større endringar i batch kan eksempelvis VS Code gjere relativt avansert søk-og-erstatt-operasjonar, eller ein kan skrive pythonkode som gjer jobben. Ein får opp endringane i endringsloggen, og kan køyre dbt-prosjektet for å sjå om alt kompilerer og køyrer som det skal. Gjer ein noko feil kan ofte ein test oppdage det, eller så har ein endringshistorikken i git-repoet og kan gå tilbake att ved behov.
Så ikkje ver redd for å gjere ting på ein ny måte - omfattande endringar er ikkje så omfattande i dbt.