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_column_description_populated |
Columns declared in a model's properties file must have a populated description. |
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_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_names |
Columns declared in a model's properties file must have a name that matches the supplied regex. |
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_columns_have_meta_keys |
Columns defined for models must have the specified keys in the |
check_model_columns_have_relationship_tests |
Columns matching a regex pattern must have a |
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_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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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_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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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_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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | |
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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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
Source code in src/dbt_bouncer/checks/manifest/models/columns.py
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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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_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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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_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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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. |
language |
Literal[python, sql] | None
|
Limit check to models written in the specified language. |
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):