Skip to content
dbt-model-writer logo

dbt Model Writer

dbt-model-writer

Writes, edits, and creates dbt models following best practices. Use when user needs to create new dbt SQL models, update existing models, or convert raw SQL to dbt format. Handles staging, intermediate, and mart models with proper config blocks, CTEs, and documentation.

SKILL.md

Full skill instructions

dbt Model Writer

Expert dbt model creation and editing skill for analytics engineering.

When to Use This Skill

Activate this skill when the user mentions:

  • "Create a dbt model"
  • "Write a dbt SQL file"
  • "Convert this SQL to dbt"
  • "Add a staging/​intermediate/​mart model"
  • "Update this dbt model"
  • "Fix this dbt model"

Core Capabilities

1. Model Creation

Create new dbt models with:

  • Proper config blocks (materialization, tags, schema)
  • Descriptive CTE structure
  • Inline documentation comments
  • Source and ref() functions
  • Appropriate Jinja templating

2. Model Types

Staging Models (stg_*.sql)

  • Purpose: Clean and standardize raw source data
  • Materialization: Usually view
  • Pattern: One-to-one with source tables
  • Transformations: Column renaming, type casting, basic cleaning
{{
  config(
    materialized='view',
    tags=['staging']
  )
}}

with source as (
    select * from {{ source('raw', 'orders') }}
),

renamed as (
    select
        order_id,
        customer_id,
        order_date,
        status,
        -- Standardize column names and types
        cast(total_amount as decimal(10,2)) as total_amount,
        created_at,
        updated_at
    from source
)

select * from renamed

Intermediate Models (int_*.sql)

  • Purpose: Complex business logic, joins, denormalization
  • Materialization: Usually ephemeral or view
  • Pattern: Combine multiple staging models
  • Transformations: Business calculations, complex joins
{{
  config(
    materialized='ephemeral',
    tags=['intermediate']
  )
}}

with orders as (
    select * from {{ ref('stg_orders') }}
),

customers as (
    select * from {{ ref('stg_customers') }}
),

order_items as (
    select * from {{ ref('stg_order_items') }}
),

order_totals as (
    select
        order_id,
        count(*) as item_count,
        sum(quantity) as total_quantity,
        sum(quantity * price) as gross_total
    from order_items
    group by order_id
),

joined as (
    select
        o.order_id,
        o.customer_id,
        c.customer_name,
        o.order_date,
        ot.item_count,
        ot.total_quantity,
        ot.gross_total
    from orders o
    join customers c on o.customer_id = c.customer_id
    join order_totals ot on o.order_id = ot.order_id
)

select * from joined

Mart Models (fct_*.sql or dim_*.sql)

  • Purpose: Analytics-ready tables optimized for BI tools
  • Materialization: Usually table or incremental
  • Pattern: Final dimensional models (facts and dimensions)
  • Transformations: Aggregations, final business metrics
{{
  config(
    materialized='incremental',
    unique_key='order_id',
    cluster_by=['order_date'],
    tags=['mart', 'daily']
  )
}}

with orders as (
    select * from {{ ref('int_order_details') }}
)

select
    order_id,
    customer_id,
    order_date,
    item_count,
    total_quantity,
    gross_total,
    current_timestamp() as dbt_updated_at
from orders

{% if is_incremental() %}
    -- Only process new or updated orders
    where order_date >= (select max(order_date) from {{ this }})
{% endif %}

3. Config Block Standards

Essential config parameters:

{{
  config(
    materialized='table',  -- table|view|incremental|ephemeral
    schema='analytics',    -- custom schema
    alias='my_table',      -- custom table name
    tags=['daily', 'core'], -- organizational tags
    cluster_by=['date', 'id'], -- Snowflake clustering
    unique_key='id',       -- for incremental
    on_schema_change='sync_all_columns', -- incremental schema changes
    pre_hook="ALTER TABLE {{ this }} ...",
    post_hook="GRANT SELECT ON {{ this }} ..."
  )
}}

4. Incremental Strategy Patterns

Append-Only (Insert New Records)

{% if is_incremental() %}
    where created_at > (select max(created_at) from {{ this }})
{% endif %}

Update Existing Records (Merge)

{{
  config(
    materialized='incremental',
    unique_key='id',
    incremental_strategy='merge'
  )
}}

Delete + Insert

{{
  config(
    materialized='incremental',
    unique_key='date_day',
    incremental_strategy='delete+insert'
  )
}}

5. Documentation Standards

Always create corresponding schema.yml entries:

version: 2

models:
  - name: fct_orders
    description: "Fact table for order transactions"
    columns:
      - name: order_id
        description: "Unique order identifier"
        tests:
          - unique
          - not_null
      - name: customer_id
        description: "Foreign key to dim_customers"
        tests:
          - not_null
          - relationships:
              to: ref('dim_customers')
              field: customer_id
      - name: order_date
        description: "Date order was placed"
        tests:
          - not_null
      - name: total_amount
        description: "Total order value in USD"
        tests:
          - not_null

6. Jinja Best Practices

Use ref() for model dependencies

select * from {{ ref('stg_orders') }}

Use source() for raw data

select * from {{ source('raw_db', 'orders') }}

Environment-specific logic

{% if target.name == 'prod' %}
    -- Production-specific logic
{% else %}
    -- Dev/​test logic
{% endif %}

Macros for reusable logic

{{ cents_to_dollars('price_cents') }} as price_dollars

Workflow Process

  1. Understand Requirements

    • Ask about model purpose and layer (staging/​intermediate/​mart)
    • Identify source tables or upstream models
    • Determine materialization needs
    • Clarify any business logic
  2. Read Existing Context

    • Check dbt_project.yml for project structure
    • Look for similar existing models
    • Review naming conventions in use
    • Check for available macros
  3. Write the Model

    • Start with config block
    • Build CTEs from source up
    • Apply transformations step-by-step
    • Add inline comments for complex logic
    • Final select statement
  4. Create Documentation

    • Generate schema.yml entry
    • Add column descriptions
    • Include appropriate tests
  5. Validate

    • Check for syntax errors
    • Ensure all refs/​sources exist
    • Verify config parameters
    • Confirm naming conventions

Common Patterns to Apply

Deduplication

with deduped as (
    select
        *,
        row_number() over (
            partition by id 
            order by updated_at desc
        ) as row_num
    from source
    where row_num = 1
)

Type 2 SCD (Slowly Changing Dimension)

with current_records as (
    select * from {{ ref('stg_customers') }}
),

historical_records as (
    select * from {{ this }}
    where is_current = true
),

changes as (
    select
        c.*,
        h.customer_key,
        case
            when h.customer_key is null then true
            when c.customer_name != h.customer_name then true
            else false
        end as has_changed
    from current_records c
    left join historical_records h
        on c.customer_id = h.customer_id
)
-- ... SCD logic continues

Surrogate Key Generation

{{ dbt_utils.generate_surrogate_key(['order_id', 'line_number']) }} as order_line_key

Error Handling

If encountering issues:

  1. Check compiled SQL in target/​compiled/
  2. Verify all referenced models exist
  3. Validate Jinja syntax
  4. Ensure source definitions exist
  5. Check for circular dependencies

Quality Checklist

Before completing, verify:

  • Config block with appropriate materialization
  • All CTEs have descriptive names
  • Complex logic has comments
  • Uses ref() for models, source() for raw data
  • schema.yml entry created with tests
  • Column descriptions added
  • Follows project naming conventions
  • No hardcoded values (use vars or macros)
  • Incremental logic correct (if applicable)
  • Efficient SQL (appropriate JOINs and filters)

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View