Locking a model's shape down with a contract
dbt model contracts let you enforce the shape of a model's output—its column names, data types, and (optionally) constraints—before the model is allowed to build. Contracts act as a guardrail so downstream consumers can trust that a model's interface won't silently change, and dbt will fail the build if the actual result doesn't match the declared contract.
1 · Learn the must-know
- You enable a contract by setting 'contract: {enforced: true}' in the model's config (in the .yml file or config block), which requires you to explicitly declare 'columns' with 'name' and '
data_type' for every column the model returns. - When a contract is enforced, dbt builds the model using an explicit create-table/view statement with the declared column names and types (rather than 'select *'), so a mismatch between the query's actual output and the contract causes the run to fail before the object is created or swapped.
- Constraints (e.g., '
not_null', 'primary_key', 'foreign_key', 'check') can be added on top of the contract but support varies by adapter/warehouse—some are enforced at build time, others are informational only, and unsupported constraints will raise errors or be ignored depending on the platform. - Contracts are most commonly applied to models intended as stable interfaces—typically models materialized as table or incremental, and especially those exposed to other teams, tools, or marked as part of a public/versioned model contract via 'access' and '
latest_version' governance features. - If you change a contracted model's columns, types, or constraints, you must bump the model's version (using dbt's model versioning) or update the contract deliberately; unannounced breaking changes will simply fail CI/builds rather than pass silently.
- A common gotcha is forgetting to specify '
data_type' precisely enough (e.g., varchar length, numeric precision/scale) to match warehouse-specific type requirements, which causes contract enforcement failures even when the logical type is correct.
2 · Check your understanding
You enforce a contract on stg_orders with these columns declared:
columns:
- name: order_id
data_type: int
- name: amount
data_type: numeric(18,2)Running dbt build produces this error:
Compilation Error
This model has an enforced contract that failed.
Please ensure the name, data_type, and number of columns in your model match the contract.
...
amount | numeric(38,2) | numeric(18,2) | data type mismatchWhy did this happen?
What you have tried across dbt Analytics Engineering's objectives, not a readiness score.
Developing and optimizing dbt models45.16% of the exam*0 of 14 tried
Managing dbt models governance9.68% of the exam*0 of 3 tried
Debugging data modeling errors16.13% of the exam*0 of 5 tried
Troubleshooting and optimizing dbt pipelines6.45% of the exam*0 of 2 tried
Implementing dbt tests9.68% of the exam*0 of 3 tried
Implementing and maintaining external dependencies6.45% of the exam*0 of 2 tried
Leveraging the dbt state6.45% of the exam*0 of 2 tried
* Our estimate. dbt Labs publishes no section weights.
3 · Keep going
Ready for more? Take a weighted mock or try free practice questions.