dbt.
Analytics engineering with dbt — models, refs, tests, snapshots, incremental builds, and the transformation layer of the warehouse.
Beginner
Start here — no prior experience needed
Your First dbt Model
Set up a dbt project on DuckDB, load seed data, build a model with dbt run, and read the SQL dbt actually sent to the warehouse.
Models, ref, and the DAG
How ref builds a dependency graph, why layering into staging and marts pays off, and the selector syntax that runs exactly the models you changed.
Sources and Freshness Checks
Declare raw tables as sources so lineage starts at the loader, then let dbt source freshness fail the build when data stops arriving.
Testing Data with dbt
Generic tests, singular tests, and custom ones — plus how to see the rows that failed and why dbt build stops a bad model reaching your marts.
Materializations: View, Table, Ephemeral
The same SELECT stored four different ways — what dbt runs for each, how config precedence resolves, and how to choose without guessing.
Intermediate
For developers with core concepts down
Incremental Models
Build only the new rows: is_incremental, unique_key, merge strategies, and the late-arriving data problem that silently loses records.
Jinja and Macros
Generate repetitive SQL with loops, factor logic into macros, read what dbt compiled, and query the warehouse at compile time with run_query.
Snapshots and Slowly Changing Dimensions
Source tables overwrite history. Snapshots capture it — the timestamp and check strategies, the dbt_valid_from columns, and how to query a row as it was.
Advanced
Production-grade patterns for experienced engineers
Documentation, Contracts, and Lineage
Doc blocks, exposures and persisted comments, then model contracts and access levels that turn a mart into a stable interface other teams can build on.
Deployment and Slim CI
Run dbt in production: environments and targets, artifacts, state:modified with defer for CI that builds only what changed, and retrying a failed run.