dbt Skill for Claude
Comprehensive dbt guidance: project structure, modeling, testing, CI/CD, production patterns. Targets Snowflake and BigQuery. Beginner-friendly with progressive scaling.
When to Use
Activate when: creating/modifying dbt models, choosing materializations, structuring layers, setting up tests, implementing CI/CD, configuring sources/freshness, writing Jinja macros, reviewing dbt projects, making analytics engineering decisions.
Skip when: basic SQL syntax, warehouse admin, raw pipeline config (Fivetran/Airbyte), BI tool config.
Core Principles
- DRY via ref()/source() -- never hardcode table names
- Single Source of Truth -- each concept defined once; staging = entry point, marts = consumer interface
- Idempotent Transformations --
dbt run twice produces identical results
- Test Everything -- every model has at minimum PK uniqueness and not-null tests
- Progressive Complexity -- start with views/tables, add complexity when volume demands it
Project Structure
dbt_project/
├── dbt_project.yml
├── packages.yml
├── profiles.yml # local only, not committed
├── models/
│ ├── staging/ # 1:1 with source tables
│ │ └── <source>/
│ │ ├── _<source>__models.yml
│ │ ├── _<source>__sources.yml
│ │ └── stg_<source>__<entity>.sql
│ ├── intermediate/ # business logic, joins, pivots
│ │ └── <domain>/
│ └── marts/ # business-facing tables
│ └── <domain>/
│ ├── _<domain>__models.yml
│ ├── fct_<entity>.sql
│ └── dim_<entity>.sql
├── macros/
├── tests/
│ └── generic/
├── seeds/
├── snapshots/
└── analyses/
Layer Decision Matrix
| Layer |
Materialization |
Purpose |
Naming |
Tests |
| Staging |
view |
Clean/rename raw data, 1:1 with source |
stg_<source>__<entity> |
not_null, unique on PK |
| Intermediate |
ephemeral |
Business logic, joins, pivots |
int_<entity>_<verb>ed |
Tested via downstream |
| Marts |
table/incremental |
Business-facing facts and dimensions |
fct_<entity>, dim_<entity> |
Full coverage |
Materialization Decision Matrix
| Situation |
Materialization |
Why |
| Staging models |
view |
Always fresh, minimal storage |
| Intermediate logic |
ephemeral |
Zero cost, inlined as CTE |
| Marts < 100M rows |
table |
Simple, fast reads |
| Marts > 100M rows |
incremental |
Process only new/changed data |
| SCD Type 2 |
snapshot |
Track historical changes |
ref() and source() Rules
source() only in staging -- staging is the sole gateway to raw data
ref() everywhere else
- Never skip layers -- marts must not ref() staging directly
- Never hardcode schema names
SQL Style
- Leading commas, lowercase keywords, CTEs over subqueries
- Explicit columns in marts (no
select *), final CTE named final
- 4-space indentation, one column per line
Source Configuration
Define sources in _<source>__sources.yml with loaded_at_field and freshness thresholds. Configure warn_after and error_after per table.
| Concept |
Snowflake |
BigQuery |
| Top-level container |
Database |
Project |
| Schema grouping |
Schema |
Dataset |
Warehouse Quick Reference
| Config |
Snowflake |
BigQuery |
| Profile type |
snowflake |
bigquery |
| Auth |
User/password or key-pair |
OAuth or service account |
| Schema gen |
database.schema.model |
project.dataset.model |
| Incremental default |
merge |
merge |
| Partitioning |
Automatic micro-partitions |
partition_by required for large tables |
| Clustering |
cluster_by (automatic) |
cluster_by (manual) |
| Cost model |
Credits (compute time) |
Bytes scanned / Slots |
Common Commands
| Command |
Purpose |
dbt build |
Run + test in DAG order (recommended) |
dbt build --select +model |
Build model and all ancestors |
dbt build --select model+ |
Build model and all descendants |
dbt build --select tag:finance |
All models tagged finance |
dbt build --select state:modified+ |
Modified + descendants (Slim CI) |
dbt source freshness |
Check source freshness |
dbt deps |
Install packages |
dbt docs generate && dbt docs serve |
Documentation site |
Gotchas
ref() only in staging-and-above, source() only in staging — using source() in marts bypasses the staging contract and breaks lineage
- Incremental models without
unique_key silently duplicate rows on re-runs — always set unique_key for merge strategy
ephemeral models can't be tested directly or selected with dbt test --select — test via downstream consumers
dbt run doesn't run tests — always use dbt build to get run + test in DAG order
--full-refresh on a large incremental model can blow warehouse credits — scope with --select first
- Jinja whitespace control:
{%- -%} vs {% %} — trailing whitespace breaks compile output silently
packages.yml version ranges (>=1.0,<2.0) can pull breaking changes — pin exact versions in production
-- WRONG: source() in marts (skips staging layer)
SELECT * FROM {{ source('stripe', 'payments') }}
-- RIGHT: ref staging model
SELECT * FROM {{ ref('stg_stripe__payments') }}
-- WRONG: incremental without unique_key (duplicates on re-run)
{{ config(materialized='incremental') }}
-- RIGHT: always specify unique_key
{{ config(materialized='incremental', unique_key='payment_id') }}
Reference Files
Load on demand when detailed guidance is needed:
| Reference |
Topics |
| Testing & Quality |
Schema/generic/singular/unit tests, dbt-expectations, layer strategy |
| CI/CD & Deployment |
Slim CI, GitHub Actions, dbt Cloud, environments, blue/green, SQLFluff |
| Jinja, Macros & Packages |
Jinja fundamentals, custom macros, packages, debugging |
| Incremental & Performance |
Microbatch, merge, delete+insert, insert_overwrite, warehouse tuning |
| Data Quality & Observability |
Source freshness, Elementary, anomaly detection, alerting, incidents |
| Semantic Layer & Governance |
MetricFlow, contracts, versions, access controls, dbt Mesh |
License
Apache License 2.0. See LICENSE file for full terms.
Copyright 2026 Daniel Song
1---2name: dbt-skill3description: Use when working with dbt (data build tool) - creating models, writing tests, CI/CD pipelines, materializations, sources, staging/intermediate/marts layers, Snowflake/BigQuery warehouse configuration, incremental strategies, Jinja macros, data quality, semantic layer, or making analytics engineering decisions4license: Apache-2.05---67# dbt Skill for Claude89Comprehensive dbt guidance: project structure, modeling, testing, CI/CD, production patterns. Targets Snowflake and BigQuery. Beginner-friendly with progressive scaling.1011## When to Use1213Activate when: creating/modifying dbt models, choosing materializations, structuring layers, setting up tests, implementing CI/CD, configuring sources/freshness, writing Jinja macros, reviewing dbt projects, making analytics engineering decisions.1415Skip when: basic SQL syntax, warehouse admin, raw pipeline config (Fivetran/Airbyte), BI tool config.1617## Core Principles18191. **DRY via ref()/source()** -- never hardcode table names202. **Single Source of Truth** -- each concept defined once; staging = entry point, marts = consumer interface213. **Idempotent Transformations** -- `dbt run` twice produces identical results224. **Test Everything** -- every model has at minimum PK uniqueness and not-null tests235. **Progressive Complexity** -- start with views/tables, add complexity when volume demands it2425## Project Structure2627```28dbt_project/29├── dbt_project.yml30├── packages.yml31├── profiles.yml # local only, not committed32├── models/33│ ├── staging/ # 1:1 with source tables34│ │ └── <source>/35│ │ ├── _<source>__models.yml36│ │ ├── _<source>__sources.yml37│ │ └── stg_<source>__<entity>.sql38│ ├── intermediate/ # business logic, joins, pivots39│ │ └── <domain>/40│ └── marts/ # business-facing tables41│ └── <domain>/42│ ├── _<domain>__models.yml43│ ├── fct_<entity>.sql44│ └── dim_<entity>.sql45├── macros/46├── tests/47│ └── generic/48├── seeds/49├── snapshots/50└── analyses/51```5253## Layer Decision Matrix5455| Layer | Materialization | Purpose | Naming | Tests |56|-------|----------------|---------|--------|-------|57| Staging | `view` | Clean/rename raw data, 1:1 with source | `stg_<source>__<entity>` | not_null, unique on PK |58| Intermediate | `ephemeral` | Business logic, joins, pivots | `int_<entity>_<verb>ed` | Tested via downstream |59| Marts | `table`/`incremental` | Business-facing facts and dimensions | `fct_<entity>`, `dim_<entity>` | Full coverage |6061## Materialization Decision Matrix6263| Situation | Materialization | Why |64|-----------|----------------|-----|65| Staging models | `view` | Always fresh, minimal storage |66| Intermediate logic | `ephemeral` | Zero cost, inlined as CTE |67| Marts < 100M rows | `table` | Simple, fast reads |68| Marts > 100M rows | `incremental` | Process only new/changed data |69| SCD Type 2 | `snapshot` | Track historical changes |7071## ref() and source() Rules72731. `source()` only in staging -- staging is the sole gateway to raw data742. `ref()` everywhere else753. Never skip layers -- marts must not ref() staging directly764. Never hardcode schema names7778## SQL Style7980- Leading commas, lowercase keywords, CTEs over subqueries81- Explicit columns in marts (no `select *`), final CTE named `final`82- 4-space indentation, one column per line8384## Source Configuration8586Define sources in `_<source>__sources.yml` with `loaded_at_field` and freshness thresholds. Configure `warn_after` and `error_after` per table.8788| Concept | Snowflake | BigQuery |89|---------|-----------|----------|90| Top-level container | Database | Project |91| Schema grouping | Schema | Dataset |9293## Warehouse Quick Reference9495| Config | Snowflake | BigQuery |96|--------|-----------|----------|97| Profile type | `snowflake` | `bigquery` |98| Auth | User/password or key-pair | OAuth or service account |99| Schema gen | `database.schema.model` | `project.dataset.model` |100| Incremental default | `merge` | `merge` |101| Partitioning | Automatic micro-partitions | `partition_by` required for large tables |102| Clustering | `cluster_by` (automatic) | `cluster_by` (manual) |103| Cost model | Credits (compute time) | Bytes scanned / Slots |104105## Common Commands106107| Command | Purpose |108|---------|---------|109| `dbt build` | Run + test in DAG order (recommended) |110| `dbt build --select +model` | Build model and all ancestors |111| `dbt build --select model+` | Build model and all descendants |112| `dbt build --select tag:finance` | All models tagged `finance` |113| `dbt build --select state:modified+` | Modified + descendants (Slim CI) |114| `dbt source freshness` | Check source freshness |115| `dbt deps` | Install packages |116| `dbt docs generate && dbt docs serve` | Documentation site |117118## Gotchas119120- `ref()` only in staging-and-above, `source()` only in staging — using `source()` in marts bypasses the staging contract and breaks lineage121- Incremental models without `unique_key` silently duplicate rows on re-runs — always set `unique_key` for merge strategy122- `ephemeral` models can't be tested directly or selected with `dbt test --select` — test via downstream consumers123- `dbt run` doesn't run tests — always use `dbt build` to get run + test in DAG order124- `--full-refresh` on a large incremental model can blow warehouse credits — scope with `--select` first125- Jinja whitespace control: `{%- -%}` vs `{% %}` — trailing whitespace breaks `compile` output silently126- `packages.yml` version ranges (`>=1.0,<2.0`) can pull breaking changes — pin exact versions in production127128```sql129-- WRONG: source() in marts (skips staging layer)130SELECT * FROM {{ source('stripe', 'payments') }}131-- RIGHT: ref staging model132SELECT * FROM {{ ref('stg_stripe__payments') }}133134-- WRONG: incremental without unique_key (duplicates on re-run)135{{ config(materialized='incremental') }}136-- RIGHT: always specify unique_key137{{ config(materialized='incremental', unique_key='payment_id') }}138```139140## Reference Files141142Load on demand when detailed guidance is needed:143144| Reference | Topics |145|-----------|--------|146| [Testing & Quality](references/testing-quality.md) | Schema/generic/singular/unit tests, dbt-expectations, layer strategy |147| [CI/CD & Deployment](references/ci-cd-deployment.md) | Slim CI, GitHub Actions, dbt Cloud, environments, blue/green, SQLFluff |148| [Jinja, Macros & Packages](references/jinja-macros-packages.md) | Jinja fundamentals, custom macros, packages, debugging |149| [Incremental & Performance](references/incremental-performance.md) | Microbatch, merge, delete+insert, insert_overwrite, warehouse tuning |150| [Data Quality & Observability](references/data-quality-observability.md) | Source freshness, Elementary, anomaly detection, alerting, incidents |151| [Semantic Layer & Governance](references/semantic-layer-governance.md) | MetricFlow, contracts, versions, access controls, dbt Mesh |152153## License154155Apache License 2.0. See LICENSE file for full terms.156157**Copyright 2026 Daniel Song**