Document a dbt project — model and column descriptions in schema.yml, source definitions, exposures, doc blocks, and generated docs/lineage. Use when adding descriptions to dbt models, documenting sources or dashboards as exposures, setting up dbt docs, or improving data catalog coverage.
Scanned 9/1/2026
Install to Claude Code
npx -y skills add Unknown-333/awesome-data-engineering-skills --skill documenting-dbt-models --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Documenting Dbt Models?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/unknown-333-documenting-dbt-models)More formats (shields.io, HTML) on the badges page.
---
name: documenting-dbt-models
description: Document a dbt project — model and column descriptions in schema.yml, source definitions, exposures, doc blocks, and generated docs/lineage. Use when adding descriptions to dbt models, documenting sources or dashboards as exposures, setting up dbt docs, or improving data catalog coverage.
---
# Documenting dbt Models
## When to use
- Adding or improving descriptions for models, columns, and sources.
- Registering downstream dashboards/apps as exposures for lineage.
- Setting up `dbt docs` generation and reusable doc blocks.
- Do NOT use for writing tests (use `testing-dbt-projects`).
## Workflow
```
- [ ] Describe each model: what it is, its grain, and who uses it
- [ ] Describe key columns (keys, enums, money, dates)
- [ ] Reuse repeated definitions with doc blocks
- [ ] Register BI dashboards as exposures
- [ ] Run dbt docs generate and review lineage
```
1. **Model description** states the grain and purpose in one or two lines — the
grain is the most valuable fact for a consumer.
2. **Column descriptions** for keys, enums, money, and dates; skip self-evident
ones to avoid noise.
3. **Doc blocks** (`{% docs %}`) for definitions reused across models (e.g. what
"active customer" means) so they stay consistent.
4. **Exposures** connect models to the dashboards/ML jobs that consume them, so
lineage and `dbt build --select +exposure` work.
## Patterns
**schema.yml with descriptions:**
```yaml
models:
- name: fct_orders
description: "One row per order line. Grain: order_id + line_number. Feeds Finance revenue dashboard."
columns:
- name: order_id
description: "Natural order identifier from the shop system."
- name: status
description: '{{ doc("order_status") }}'
```
**Reusable doc block** (in a `.md` file under `models/`):
```markdown
{% docs order_status %}
Lifecycle status: placed → shipped → delivered, or cancelled at any point.
{% enddocs %}
```
**Exposure:**
```yaml
exposures:
- name: revenue_dashboard
type: dashboard
maturity: high
url: https://bi.example.com/revenue
depends_on:
- ref('fct_orders')
- ref('dim_customer')
owner: { name: Data Team, email: data@example.com }
```
Then `dbt docs generate && dbt docs serve` renders descriptions and a lineage
graph including exposures.
## Common pitfalls
- **Restating the column name** ("order_id is the order id") — add only what the
name cannot convey (source, units, grain, meaning of enum values).
- **Omitting the grain** — the single most useful line for any consumer.
- **Duplicating definitions** across models instead of using a doc block — they
drift apart.
- **No exposures** — lineage stops at the warehouse and you cannot see what breaks
downstream when a model changes.

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!