Columns#
Note
The below checks require manifest.json to be present.
Checks related to model column definitions, types, and constraints.
Functions:
| Name | Description |
|---|---|
check_model_columns_have_relationship_tests |
Columns matching a regex pattern must have a |
check_model_columns_have_meta_keys |
Columns defined for models must have the specified keys in the |
check_model_columns_have_types |
Columns defined for models must have a |
check_model_has_constraints |
Table and incremental models must have the specified constraint types defined. |
check_model_single_primary_key |
Models must have at most one column-level primary key constraint. |
check_model_column_has_specified_test |
Columns declared in a model's properties file that match the specified regexp pattern must have a specified test. |
check_model_column_description_populated |
Columns declared in a model's properties file must have a populated description. |
check_model_column_name_complies_to_column_type |
Columns with the specified regexp naming pattern must have declared data types that comply to the specified regexp pattern or list of data types. |
check_model_column_type_complies_to_column_name |
Columns with the specified declared data type must have names that comply to the specified regexp pattern. |
check_model_column_names |
Columns declared in a model's properties file must have a name that matches the supplied regex. |
check_model_columns_have_relationship_tests
#
Columns matching a regex pattern must have a relationships test, optionally validating the target column and model.
Rationale
Foreign-key columns that are never validated with a relationships test can silently contain orphaned IDs, leading to incorrect join results and data quality issues that are hard to trace. This check ensures that columns following a naming convention (e.g. _fk) are always backed by a referential integrity test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column_name_pattern
|
str
|
Regex pattern to match column names that require a relationships test. |
required |
target_column_pattern
|
str | None
|
Regex pattern the target column ( |
None
|
target_model_pattern
|
str | None
|
Regex pattern the target model of the relationships test must match. If not provided, any target model is accepted. |
None
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
- name: check_model_columns_have_relationship_tests
column_name_pattern: "_fk$"
target_column_pattern: "_pk$"
target_model_pattern: "^dim_|^fact_"
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_columns_have_meta_keys
#
Columns defined for models must have the specified keys in the meta config.
Rationale
Column-level metadata such as owner or pii flags is essential for data governance, access control, and cataloguing. Without enforcement, metadata is applied inconsistently, making it difficult to identify sensitive columns or assign accountability across a large project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
NestedDict
|
A list (that may contain sub-lists) of required keys. |
required |
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_columns_have_types
#
Columns defined for models must have a data_type declared.
Rationale
Declaring column data types is a prerequisite for enforced dbt contracts and enables downstream consumers to understand the expected format of each field without querying the warehouse. It also prevents type-mismatch errors in tools that consume the schema at build time.
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_has_constraints
#
Table and incremental models must have the specified constraint types defined.
Rationale
Database constraints such as primary_key and not_null enforce data integrity at the warehouse level, providing a safety net that goes beyond dbt tests. Requiring them on materialised models ensures that quality guarantees survive even when dbt tests are skipped or not run on every refresh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
required_constraint_types
|
list[Literal[check, custom, foreign_key, not_null, primary_key, unique]]
|
List of constraint types that must be present on the model. |
required |
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
- name: check_model_has_constraints
required_constraint_types:
- primary_key
include: ^models/marts
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_single_primary_key
#
Models must have at most one column-level primary key constraint.
Rationale
Declaring more than one column-level primary-key constraint in a dbt model is almost always a modelling mistake — it implies multiple independent identity columns, which is semantically ambiguous and can confuse downstream consumers. This check flags models with two or more column-level primary_key constraints so the author can consolidate them into a single-column PK or a composite constraint at model level.
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_column_has_specified_test
#
Columns declared in a model's properties file that match the specified regexp pattern must have a specified test.
Rationale
Naming conventions communicate expectations: a column named is_active implies it is boolean and never null; a column ending in _id implies it is a valid foreign key. Without enforcement, these implicit contracts go untested, and referential integrity issues or null values can silently corrupt downstream aggregations. This check bridges naming conventions and data quality by automatically requiring specific tests on columns that match a pattern, eliminating the manual overhead of reviewing every column individually.
This is the manifest-only analogue of check_column_has_specified_test, which requires catalog.json. It only evaluates columns declared in model.columns, i.e. columns present in the model's properties file; columns that exist in the warehouse but are not documented are invisible to this check. Unlike the catalog check it has no case_sensitive parameter: both the column names and the tests are read from manifest.json, so no cross-artifact casing mismatch is possible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column_name_pattern
|
str
|
Regex pattern to match the column name. |
required |
test_name
|
str
|
Name of the test to check for. |
required |
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
tests |
list[TestNode]
|
List of TestNode objects parsed from |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
- name: check_model_column_has_specified_test
column_name_pattern: ^is_.*
test_name: not_null
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_column_description_populated
#
Columns declared in a model's properties file must have a populated description.
Rationale
Column-level documentation is where data consumers spend most of their time: understanding what is_active means, whether amount is in cents or pounds, or which ID to join on. Without column descriptions, analysts guess, make mistakes, and create conflicting metrics. This check ensures every column is explained, which is especially valuable for data catalogues and BI tool integrations that surface these descriptions automatically.
This is the manifest-only analogue of check_column_description_populated, which requires catalog.json. It only evaluates columns declared in model.columns, i.e. columns present in the model's properties file; use the catalog check check_columns_are_all_documented to detect columns that exist in the warehouse but are undocumented.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_description_length
|
int | None
|
Minimum length required for the description to be considered populated. |
None
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
- name: check_model_column_description_populated
min_description_length: 25 # Setting a stricter requirement for description length
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
check_model_column_name_complies_to_column_type
#
Columns with the specified regexp naming pattern must have declared data types that comply to the specified regexp pattern or list of data types.
Rationale
Naming conventions that encode data types (e.g. is_ prefix for booleans, _date suffix for dates, _id suffix for integers) are a common and effective way to make schemas self-describing. Without enforcement, these conventions drift over time: a column named is_active might be stored as an integer in one model and a boolean in another, causing silent cast errors downstream. This check ties naming patterns to data types, catching mismatches at CI time rather than in production queries.
This is the manifest-only analogue of check_column_name_complies_to_column_type, which requires catalog.json. It only evaluates columns declared in model.columns and compares against the data_type declared in the properties file, not the type physically introspected from the warehouse. Columns with no declared data_type are skipped rather than failed — use check_model_columns_have_types to enforce that a type is declared.
Note: One of type_pattern or types must be specified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column_name_pattern
|
str
|
Regex pattern to match the column name. |
required |
type_pattern
|
str | None
|
Regex pattern to match the data types. |
None
|
types
|
list[str] | None
|
List of data types to check. |
None
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
# Columns whose names end with "_date" must be of type DATE.
- name: check_model_column_name_complies_to_column_type
column_name_pattern: .*_date$
types:
- DATE
manifest_checks:
# Snake-case columns must not be a STRUCT type.
- name: check_model_column_name_complies_to_column_type
column_name_pattern: ^[a-z_]*$
type_pattern: ^(?!STRUCT)
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | |
check_model_column_type_complies_to_column_name
#
Columns with the specified declared data type must have names that comply to the specified regexp pattern.
Rationale
This is the reverse of check_model_column_name_complies_to_column_type. While that check ensures columns with a given naming pattern have the correct data type, this check ensures columns with a given data type follow the correct naming convention. For example, you may want all BOOLEAN columns to start with is_ or has_, or all DATE columns to end with _date. Enforcing this direction catches columns that have the right type but the wrong name — a gap the other check cannot cover.
This is the manifest-only analogue of check_column_type_complies_to_column_name, which requires catalog.json. It only evaluates columns declared in model.columns and compares against the data_type declared in the properties file, not the type physically introspected from the warehouse. Columns with no declared data_type are skipped rather than failed — use check_model_columns_have_types to enforce that a type is declared.
Note: One of type_pattern or types must be specified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column_name_pattern
|
str
|
Regex pattern that column names must match. |
required |
type_pattern
|
str | None
|
Regex pattern to match the data types. |
None
|
types
|
list[str] | None
|
List of data types to check. |
None
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
# BOOLEAN columns must start with "is_" or "has_"
- name: check_model_column_type_complies_to_column_name
column_name_pattern: ^(is|has)_.*
types:
- BOOLEAN
manifest_checks:
# Integer-like columns must end with "_id" or "_count"
- name: check_model_column_type_complies_to_column_name
column_name_pattern: .*((_id)|(_count))$
types:
- BIGINT
- INTEGER
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | |
check_model_column_names
#
Columns declared in a model's properties file must have a name that matches the supplied regex.
Rationale
Consistent column naming is the foundation of a readable and maintainable dbt project. Inconsistent casing, abbreviations, or special characters make SQL harder to write, cause join errors, and confuse data consumers who query the warehouse directly. A single enforced naming pattern (e.g. ^[a-z_]*$ for snake_case) eliminates an entire class of stylistic bugs and ensures that columns look the same whether viewed in dbt docs, a BI tool, or a raw SQL editor.
This is the manifest-only analogue of check_column_names, which requires catalog.json. It only evaluates columns declared in model.columns, i.e. columns present in the model's properties file; columns that exist in the warehouse but are undocumented are invisible to this check.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column_name_pattern
|
str
|
Regexp the column name must match. |
required |
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
Other Parameters (passed via config file):
| Name | Type | Description |
|---|---|---|
description |
str | None
|
Description of what the check does and why it is implemented. |
exclude |
str | list[str] | None
|
Regex pattern(s) to match the model path. Model paths that match any pattern will not be checked. |
include |
str | list[str] | None
|
Regex pattern(s) to match the model path. Only model paths that match any pattern will be checked. |
materialization |
Literal[ephemeral, incremental, table, view] | None
|
Limit check to models with the specified materialization. |
severity |
Literal[error, warn] | None
|
Severity level of the check. Default: |
Example(s):
manifest_checks:
- name: check_model_column_names
column_name_pattern: [a-z_] # Lowercase only, underscores allowed