Skip to main content

datacontract dbt

Work with data contracts in your dbt project.

  • datacontract dbt sync — merge an ODCS contract's schema (columns, descriptions, tags) and tests into your dbt project.
  • datacontract dbt test — run the generated, contract-managed tests.

See the dbt Integration guide.

datacontract dbt sync

Merge one or more ODCS contracts' schema (column data types, descriptions, tags, model metadata) and tests into your dbt project. Modifies the existing dbt model YAML in place (preserving comments and formatting) and, if needed, creates a new model YAML sidecar (next to a model's .sql) or singular SQL tests (under <test-paths>/datacontract_cli/).

datacontract dbt sync [CONTRACT] ...
ArgumentDescription
CONTRACTOne or more paths or globs of ODCS contracts to sync. If omitted, every *.odcs.yaml under --project-dir (and its subdirectories) is synced.
OptionDefaultDescription
--project-dircurrent dirPath to the dbt project root (must contain dbt_project.yml).
--schema-nameallWhich ODCS schema to sync, by name.
--model-resolutionnameMap an ODCS schema to a dbt model name: name or physicalName.
--prune / --no-prune--no-pruneRemove model columns and tags that are not declared in the contract.
--targetForwarded to dbt test --target.
--profiles-dirForwarded to dbt test --profiles-dir.
--run-tests / --skip-tests--skip-testsRun dbt test after syncing (requires dbt installed and on PATH). Required by --publish/--server.
--publishURL to publish the results to.
--serverThe only one in the contract, else --targetSelected ODCS server. Its type is the dialect for mapping the contract's types to column data_types, and its name is used for published results.
--ssl-verification / --no-ssl-verification--ssl-verificationSSL verification when publishing.
--debug / --no-debug--no-debugEnable debug logging.
datacontract dbt sync orders.odcs.yaml --project-dir ./warehouse

Example

Given this contract for IDs and email addresses in the orders schema:

orders-v1.odcs.yaml
apiVersion: v3.0.0
kind: DataContract
id: orders
version: 1.0.0
status: active
schema:
- name: orders
description: Customer orders
properties:
- name: order_id
physicalType: integer
primaryKey: true
- name: customer_email
description: Billing email address
logicalType: string
physicalType: text
required: true
logicalTypeOptions:
maxLength: 320

Let's assume that a minimal model properties file already exists. This is what it looks like after running datacontract dbt sync orders-v1.odcs.yaml (highlighted lines got added):

models/orders.yml
version: 2
models:
- name: orders
description: Customer orders
config:
meta:
datacontract_cli:
contract_id: orders
columns:
- name: order_id
data_type: integer
data_tests:
- not_null:
config:
severity: warn
meta:
datacontract_cli:
check: orders__order_id__field_required
include_in_tests: true
contract_versions:
- 1.0.0
generated: true
description: Check that field order_id has no missing values
- unique:
config:
severity: warn
meta:
datacontract_cli:
check: orders__order_id__field_unique
include_in_tests: true
contract_versions:
- 1.0.0
generated: true
description: Check that field order_id has no duplicate values
meta:
datacontract_cli:
generated: true
- name: customer_email
data_type: text
description: Billing email address
data_tests:
- not_null:
config:
severity: warn
meta:
datacontract_cli:
check: orders__customer_email__field_required
include_in_tests: true
contract_versions:
- 1.0.0
generated: true
description: Check that field customer_email has no missing values
meta:
datacontract_cli:
generated: true

The generated config.meta.datacontract_cli block is how dbt sync/dbt test recognize and scope managed tests; the per-column meta.datacontract_cli.generated marks a column the CLI added.

The maxLength bound becomes a self-contained singular SQL test (no dbt_utils needed). Its config() header carries the same datacontract_cli metadata:

tests/datacontract_cli/orders/orders__1_0_0__orders__customer_email__length.sql
-- AUTO-GENERATED by `datacontract dbt sync`. Do not edit.
-- Source contract: orders@1.0.0 (model: orders, check: customer_email__length)
{{ config(severity='warn', meta={"datacontract_cli": {"check": "orders__customer_email__field_length", "contract_versions": ["1.0.0"], "generated": true, "include_in_tests": true, "model": "orders", "field": "customer_email", "description": "Check that field customer_email has a length of at most 320"}}) }}
SELECT *
FROM {{ ref('orders') }}
WHERE "customer_email" IS NOT NULL
AND (LENGTH("customer_email") > 320)

datacontract dbt test

Run the contract-managed dbt tests that datacontract dbt sync generated, scoped to the requested contracts' models, report the results, and optionally publish them. Never modifies project files — run datacontract dbt sync first to (re)generate the tests. With multiple contracts, each contract's results are reported (and published) separately, followed by a summary.

datacontract dbt test [CONTRACT]...
ArgumentDescription
CONTRACTOne or more paths or globs of ODCS contracts to test. If omitted, every *.odcs.yaml under --project-dir (and its subdirectories) is tested. Non-ODCS files are skipped with a warning, and a glob that matches nothing is ignored.
OptionDefaultDescription
--project-dircurrent dirPath to the dbt project root (must contain dbt_project.yml).
--targetForwarded to dbt test --target.
--profiles-dirForwarded to dbt test --profiles-dir.
--publishURL to publish the results to.
--serverThe only one in the contract, else --targetODCS server name for published test results.
--ssl-verification / --no-...onSSL verification when publishing.
--debug / --no-debugoffEnable debug logging.
datacontract dbt test orders.odcs.yaml --project-dir ./warehouse