Skip to content
Back to skills

Building Dbt Models

ASecurity

Build well-structured dbt models — staging/intermediate/marts layers, ref() and source(), materializations, and incremental models with the right strategy. Use when creating or refactoring dbt models, choosing table vs view vs incremental, structuring a dbt project, or writing incremental logic.

  • 15 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 1, 2026
ai-agentssqltestingdebuggingrefactoring

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 1, 2026

npx -y skills add Unknown-333/awesome-data-engineering-skills --skill building-dbt-models --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Building Dbt Models?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Building Dbt Models
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/unknown-333-building-dbt-models/badge)](https://www.skillsdirectory.com/skills/unknown-333-building-dbt-models)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: building-dbt-models
description: Build well-structured dbt models — staging/intermediate/marts layers, ref() and source(), materializations, and incremental models with the right strategy. Use when creating or refactoring dbt models, choosing table vs view vs incremental, structuring a dbt project, or writing incremental logic.
---

# Building dbt Models

## When to use

- Creating or refactoring `.sql` models in a dbt project.
- Deciding materialization (view / table / incremental / ephemeral).
- Structuring layers (staging → intermediate → marts).
- Writing incremental models for large, growing tables.
- Do NOT use for test authoring (use `testing-dbt-projects`) or run failures
  (use `debugging-dbt-runs`).

## Workflow

```
- [ ] Place the model in the right layer (staging/intermediate/marts)
- [ ] Reference upstream only via ref()/source() — never hard-coded names
- [ ] Choose materialization by size and refresh needs
- [ ] For incremental, set unique_key + is_incremental() filter
- [ ] Add a schema.yml entry with tests
```

1. **Layer it.** `staging/` = one model per source table, light renaming/typing,
   materialized as views. `intermediate/` = reusable business logic. `marts/` =
   final dimensional models consumed by BI, materialized as tables.
2. **Reference correctly.** Use `{{ ref('stg_orders') }}` and
   `{{ source('shop', 'orders') }}` so dbt builds the DAG and manages
   environments. Never write raw schema.table.
3. **Pick materialization:** view (cheap, always fresh, small), table (fast reads,
   rebuilt each run), incremental (large append/update tables), ephemeral (inlined
   CTE, no object).
4. **Incremental models** process only new/changed rows.

## Patterns

**Staging model** — one per source, thin and consistent:

```sql
-- models/staging/shop/stg_orders.sql
with source as (select * from {{ source('shop', 'orders') }})
select
    order_id,
    customer_id,
    cast(order_ts as timestamp) as ordered_at,
    round(amount_cents / 100.0, 2) as amount
from source
```

**Incremental model** — filter to new rows and set an idempotent merge key:

```sql
{{ config(materialized='incremental', unique_key='order_id',
          incremental_strategy='merge') }}

select * from {{ ref('stg_orders') }}
{% if is_incremental() %}
  -- only rows newer than what we already loaded, with a lookback for late data
  where ordered_at >= (select coalesce(max(ordered_at), '1900-01-01') from {{ this }})
                      - interval '3 days'
{% endif %}
```

The `unique_key` + `merge` makes re-runs idempotent; the lookback catches
late-arriving rows. On BigQuery/Spark, prefer `insert_overwrite` on a date
partition.

## Common pitfalls

- **Hard-coded table names** instead of `ref()`/`source()` — breaks the DAG,
  lineage, and environment switching.
- **Incremental without `unique_key`** — re-runs append duplicates.
- **`max(id)` incremental filter with no lookback** — silently drops late data.
- **Business logic in staging** — keep staging thin; joins/aggregation belong in
  intermediate/marts.
- **Everything materialized as `table`** — wastes warehouse time; use views for
  small/cheap models and incremental for large ones.
- **One giant model** — split into intermediate steps for testability and reuse.

## References

- [dbt project structure conventions](references/STRUCTURE.md)

Files in this skill

  • SKILL.md3.3 KB
  • references/STRUCTURE.md1.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.