dbt Production Fact Model Template
Full incremental dbt fact model with merge strategy, deduplication, anomaly flags, and companion schema test definitions. Replace entity, PK, and column placeholders to bootstrap a production mart.
dbtIntermediateSQL
Code preview
76 linesReplace {{PLACEHOLDERS}} with your environment values, then deploy to your stack.
-- =============================================================================
-- DBT PRODUCTION FACT MODEL TEMPLATE
-- Copy to models/marts/fct_{{ENTITY}}.sql and replace {{PLACEHOLDERS}}
-- =============================================================================
{{ config(
materialized='incremental',
unique_key='{{PK_COLUMN}}',
incremental_strategy='merge',
on_schema_change='sync_all_columns',
tags=['{{DOMAIN}}', 'marts'],
meta={
'owner': '{{OWNER_TEAM}}',
'sla_hours': {{SLA_HOURS}},
'grain': 'one row per {{GRAIN_DESCRIPTION}}'
}
) }}
/*
Model: fct_{{ENTITY}}
Domain: {{DOMAIN}}
Grain: one row per {{GRAIN_DESCRIPTION}}
Source: {{SOURCE_SCHEMA}}.stg_{{SOURCE_TABLE}}
*/
WITH source AS (
SELECT *
FROM {{ ref('stg_{{SOURCE_TABLE}}') }}
{% if is_incremental() %}
WHERE _loaded_at > (SELECT COALESCE(MAX(_loaded_at), '1900-01-01') FROM {{ this }})
{% endif %}
),
deduplicated AS (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY {{PK_COLUMN}}
ORDER BY _loaded_at DESC
) AS _row_num
FROM source
),
enriched AS (
SELECT
{{PK_COLUMN}},
-- {{METRIC_COLUMNS}} - add your business columns here
{{DATE_COLUMN}},
{{AMOUNT_COLUMN}},
CASE
WHEN {{AMOUNT_COLUMN}} < 0 THEN TRUE
ELSE FALSE
END AS is_anomaly_flag,
_loaded_at,
CURRENT_TIMESTAMP() AS _dbt_updated_at
FROM deduplicated
WHERE _row_num = 1
)
SELECT * FROM enriched
-- ── Companion schema.yml tests (add to models/marts/schema.yml) ──────────────
-- models:
-- - name: fct_{{ENTITY}}
-- description: "{{DESCRIPTION}}"
-- columns:
-- - name: {{PK_COLUMN}}
-- tests: [unique, not_null]
-- - name: {{DATE_COLUMN}}
-- tests: [not_null]
-- - name: {{AMOUNT_COLUMN}}
-- tests:
-- - dbt_expectations.expect_column_values_to_be_between:
-- min_value: 0
-- max_value: {{MAX_AMOUNT}}
About this template
Full incremental dbt fact model with merge strategy, deduplication, anomaly flags, and companion schema test definitions. Replace entity, PK, and column placeholders to bootstrap a production mart.
dbtincrementalmartsanalytics engineering
Reviews
Saved a day on our orders mart
I used the dbt fact model template on our orders mart and skipped a full day of boilerplate. The schema tests caught two bad joins before we shipped to prod.
Nina Kowalski · dbt Developer · ShopNest
Downloads142
Reviews1
Rating5.0
CreatedJul 2, 2026
UpdatedJul 2, 2026