Skip to Content
The HIC Learning Exchange begins July 13, 2026. View the agenda
LabItem 10 of 22 · 45 min

dbt Training: From Installation to First Model

From installation to running your first model — with copy-pasteable commands throughout.

What you'll learn
  • Install dbt-core and a warehouse adapter inside a virtual environment
  • Initialize a dbt project and confirm the warehouse connection with dbt debug
  • Write a model, reference it with ref(), and run it with dbt run
  • Define and run schema tests, then generate and serve the documentation site
  • Use the everyday dbt command set: seed, run, test, docs, build, clean
Before you start
  • Python 3.8+ installed, with pip available on your PATH
  • A code editor (VS Code recommended)
  • Access to a warehouse — Snowflake, BigQuery, Postgres, Redshift, or DuckDB (best for live demos, no cloud account needed)
  • Git installed (optional, recommended for version control)
Download the lab files (.zip)

1. Introduction

(data build tool) lets analysts and engineers transform data already loaded into a warehouse, using plain SQL SELECT statements. dbt handles the boilerplate — turning SQL into tables or views, managing dependencies, testing, and documentation.

What you will learn: installing dbt, connecting to a warehouse, project structure, writing and running a model, testing and documenting, and the everyday commands.

2. Prerequisites

  • Python 3.8+ installed
  • A code editor (VS Code recommended)
  • Access to a warehouse — Snowflake, BigQuery, Postgres, Redshift, or DuckDB (best for live demos, no cloud account needed)
  • Git installed (optional, recommended for version control)
# check your python version python --version

3. Installing dbt

dbt ships in two parts: dbt-core (the framework) and a dbt-<adapter> package (a connector for your specific warehouse).

3.1 Create a virtual environment

python -m venv dbt-env source dbt-env/bin/activate # Mac/Linux dbt-env\Scripts\activate # Windows

3.2 Install dbt-core plus an adapter

# Postgres pip install dbt-core dbt-postgres # Snowflake pip install dbt-core dbt-snowflake # DuckDB — best for local, zero-setup demos pip install dbt-core dbt-duckdb

3.3 Verify the installation

dbt --version

You should see the dbt-core version and your installed adapter listed.

Checkpointdbt and adapter installed
You should see:
Core: - installed: 1.8.0 - latest: 1.8.0 - Up to date! Plugins: - postgres: 1.8.0 - Up to date!
Not seeing this?
  • dbt: command not found — the virtual environment isn’t active. Re-run source dbt-env/bin/activate.
  • The adapter line is missing entirely — the dbt-<adapter> package didn’t install; re-run the pip install dbt-core dbt-<adapter> command for your warehouse.

4. Setting Up Your First Project

4.1 Initialize a new project

dbt init my_dbt_project

This prompts you to name the project, choose your adapter, and enter connection credentials — stored in profiles.yml (usually at ~/.dbt/profiles.yml).

4.2 Move into the project

cd my_dbt_project

4.3 Test the connection

dbt debug
CheckpointWarehouse connection confirmed
You should see:
Connection: ... Connection test: [OK connection ok] All checks passed!
Not seeing this?
  • Connection test: [ERROR] — the credentials or host in profiles.yml are wrong; re-check the values entered during dbt init.
  • Could not find profile named 'my_dbt_project' — the profile name in dbt_project.yml doesn’t match the one in profiles.yml.

5. Project Structure

    • dbt_project.yml
    • profiles.yml
PathPurpose
dbt_project.ymlMain project config
models/Your .sql models live here
seeds/CSV files loaded as tables
snapshots/Slowly changing dimension tracking
macros/Reusable SQL (Jinja macros)
tests/Custom data tests
analyses/Ad-hoc SQL, not materialized
profiles.ymlConnection credentials — lives in ~/.dbt/, outside the project

6. Creating Your First Model

A model is simply a .sql file with a SELECT statement. dbt compiles and runs it against your warehouse.

6.1 A simple model

models/customers.sql

models/customers.sql
-- models/customers.sql select id as customer_id, first_name, last_name, email, created_at from raw.customers where email is not null

6.2 Load sample data as a seed (optional)

Add a CSV to seeds/ (e.g. seeds/raw_customers.csv), then:

dbt seed

6.3 Reference the seed from a model

models/stg_customers.sql
-- models/stg_customers.sql select id as customer_id, first_name, last_name from {{ ref('raw_customers') }}

Key concept: {{ ref(...) }} is core to dbt — it builds the dependency graph automatically and tells dbt what order to run models in.

7. Running Your Model

# run all models dbt run # run one specific model dbt run --select stg_customers # run a model + everything downstream of it dbt run --select stg_customers+ # run a model + everything upstream of it dbt run --select +stg_customers # full refresh (rebuild incremental models from scratch) dbt run --full-refresh
CheckpointModel built successfully
You should see:
1 of 1 START sql view model public.stg_customers .................. [RUN] 1 of 1 OK created sql view model public.stg_customers .............. [OK in 0.15s] Completed successfully Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1
Not seeing this?
  • ERROR creating sql view model — check the SQL syntax against your warehouse’s dialect (e.g. raw.customers doesn’t exist yet).
  • Database Error referencing a missing relation — the source table hasn’t been loaded; run dbt seed first if the model depends on seed data.

8. Testing Your Models

Built-in generic tests: unique, not_null, accepted_values, relationships.

8.1 Define tests

models/schema.yml

models/schema.yml
version: 2 models: - name: stg_customers columns: - name: customer_id tests: - unique - not_null

8.2 Run the tests

dbt test # or scoped to one model dbt test --select stg_customers
CheckpointTests passing
You should see:
1 of 2 START test not_null_stg_customers_customer_id .......... [RUN] 1 of 2 PASS not_null_stg_customers_customer_id ................. [PASS in 0.10s] 2 of 2 START test unique_stg_customers_customer_id ............. [RUN] 2 of 2 PASS unique_stg_customers_customer_id ................... [PASS in 0.09s] Completed successfully Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
Not seeing this?
  • FAIL on unique_stg_customers_customer_id — duplicate customer_id values exist upstream; check the seed/source data or a join fan-out in the model.
  • FAIL on not_null_stg_customers_customer_id — nulls slipped through; add a where filter or fix the source data.

9. Documentation

dbt auto-generates a documentation site from your models and YAML descriptions.

# build the docs dbt docs generate # serve them locally in your browser dbt docs serve

10. Command Cheat Sheet

CommandPurpose
dbt initCreate a new project
dbt debugTest warehouse connection
dbt runBuild/run all models
dbt run --select model_nameRun a specific model
dbt testRun data tests
dbt seedLoad CSV seed files as tables
dbt snapshotRun snapshot logic (SCD tracking)
dbt docs generateBuild documentation
dbt docs serveView documentation locally
dbt buildRun seeds, models, snapshots and tests together
dbt cleanRemove compiled files/artifacts
dbt compileCompile SQL without running it

11. Live Demo Flow

  1. pip install dbt-core dbt-duckdb — install
  2. dbt init demo_project — initialize
  3. dbt debug — confirm the connection
  4. Create models/customers.sql — write the first model
  5. dbt run — run it
  6. Add a test in schema.yml
  7. dbt test — run it
  8. dbt docs generate && dbt docs serve — show the documentation
  9. Modify the model and rerun dbt run --select customers — show iteration speed

12. Common Pitfalls

PitfallFix
Forgetting to activate the virtual environment before running dbt commandsActivate it first (source dbt-env/bin/activate) — a missing dbt executable is the usual symptom
Confusing profiles.yml with dbt_project.ymlprofiles.yml holds connection info and lives outside the project (~/.dbt/); dbt_project.yml holds project config and lives inside it
Not using {{ ref() }} between models, which breaks dependency trackingAlways reference other models through {{ ref() }} so dbt can build the dependency graph and run models in order
Running dbt run before dbt seed when models depend on seed dataRun dbt seed first, or use dbt build, which orders seeds, models, and tests for you

Next

Continue with Lab 3: Medallion dbt Modeling — DHIS2 Case, which applies these fundamentals to the warehouse — modeling DHIS2 aggregate and tracker data through Bronze, Silver, and Gold layers.