Data Contracts and Lineage
A data contract records the interface between a producer and consumers: ownership, grain, keys, columns, types, semantics, quality objectives, freshness, compatibility, and change process. Lineage records dependencies and transformations. Neither replaces communication, runtime monitoring, or access control.
Prerequisites
Complete dbt Data Tests and Schemas, Types, and Evolution.
Learning goals
- Separate schema enforcement from semantic and operational promises.
- Add an enforced dbt model contract with typed columns.
- Use lineage for impact analysis and incident investigation.
- Classify additive, compatible, and breaking changes.
Worked example
An enforced dbt contract checks model column names and data types before publication. Constraint enforcement varies by materialization and adapter, so data tests remain necessary.
version: 2
models:
- name: fct_events
description: One row per accepted event_id, amounts in integer minor units.
config:
materialized: table
contract:
enforced: true
columns:
- name: event_id
data_type: varchar
constraints:
- type: not_null
- type: primary_key
- name: amount_cents
data_type: integer
constraints:
- type: not_null
The dependency path raw.events → stg_events → fct_events → mart_daily_region supports table-level impact analysis. dbt's source() and ref() calls populate graph metadata and its manifest artifact. Column lineage depends on SQL parsing and feature/version support; it can omit uses in filters or joins and should not be described as complete provenance.
Adding a nullable currency column may be structurally compatible, yet semantically unsafe if consumers assume all amounts are USD. Renaming amount_cents, changing its unit, revising grain, or rewriting history is breaking. Use versioning or a migration window, identify consumers from both declared lineage and query evidence, and define rollback.
Limitations and common mistakes
- A schema registry cannot enforce metric definitions or lawful data use by itself.
- Inferred lineage can miss dynamic SQL, external scripts, extracts, and manual exports.
- Declared owners become stale without operational review.
- “Backward compatible” depends on actual consumer behavior, not only nullable columns.
- Contracts applied only at the final mart allow bad data to travel too far.
Practice
Create a change proposal for adding currency. Include default behavior, historical backfill, affected models, consumer notice, validation, rollout, and rollback.
Next steps
Continue with Warehouse Cost and Query Performance to connect model shape with measured work.
Primary sources
Checked 2026-10-15: dbt model governance, model contracts, manifest artifact, and column-level lineage caveats.