Lineage#
Note
The below checks require manifest.json to be present.
Checks related to model upstream dependencies and lineage.
Functions:
| Name | Description |
|---|---|
check_model_depends_on_macros |
Models must depend on the specified macros. |
check_model_depends_on_multiple_sources |
Models cannot reference more than one source. |
check_model_has_exposure |
Models must have an exposure. |
check_model_has_no_upstream_dependencies |
Identify if models have no upstream dependencies as this likely indicates hard-coded tables references. |
check_model_materialization_by_fanout |
Heavily-reused models must use a durable materialization. |
check_model_max_chained_views |
Models cannot have more than the specified number of upstream dependents that are not tables. |
check_model_max_fanout |
Models cannot have more than the specified number of downstream models. |
check_model_max_upstream_dependencies |
Limit the number of upstream dependencies a model has. |
check_model_depends_on_macros
#
Models must depend on the specified macros.
Rationale
Some teams mandate that certain model types always use shared macros for consistency — for example, requiring all incremental models to call dbt.is_incremental(). This check enforces those conventions, preventing models from re-implementing logic that is already standardised in a shared macro.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
criteria
|
Literal[all, any, one]
|
Whether the model must depend on any, all, or exactly one of the specified macros. Default: |
ALL
|
required_macros
|
list[str]
|
List of macros the model must depend on. All macros must specify a namespace, e.g. |
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_depends_on_macros
required_macros:
- dbt.is_incremental
- name: check_model_depends_on_macros
criteria: one
required_macros:
- my_package.sampler
- my_package.sampling
Source code in src/dbt_bouncer/checks/manifest/models/lineage.py
check_model_depends_on_multiple_sources
#
Models cannot reference more than one source.
Rationale
A model that references multiple sources often signals that raw-layer joins are being performed too early, making the model harder to test, debug, and reuse. Enforcing single-source staging models encourages a clean DAG where each staging model maps 1:1 to a source table, and joins happen in downstream intermediate or mart models.
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/lineage.py
check_model_has_exposure
#
Models must have an exposure.
Rationale
Exposures declare how dbt models are consumed by downstream tools such as dashboards, ML pipelines, or applications. Requiring mart models to be referenced in at least one exposure ensures that every curated output has a known consumer, making it easier to assess the impact of changes and avoid maintaining unused models.
Receives at execution time:
| Name | Type | Description |
|---|---|---|
exposures |
list[ExposureNode]
|
List of ExposureNode objects parsed from |
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_has_exposure
description: Ensure all marts are part of an exposure.
include: ^models/marts
Source code in src/dbt_bouncer/checks/manifest/models/lineage.py
check_model_has_no_upstream_dependencies
#
Identify if models have no upstream dependencies as this likely indicates hard-coded tables references.
Rationale
A model with zero upstream dependencies is almost certainly using hard-coded table references (FROM schema.table) instead of ref() or source(). This breaks dbt's dependency graph, meaning the model won't run in the correct order, won't appear in lineage, and won't benefit from environment-aware compilation.
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/lineage.py
check_model_materialization_by_fanout
#
Heavily-reused models must use a durable materialization.
Rationale
A model consumed by many downstream models but materialized as a view re-executes its full query logic on every downstream build, multiplying warehouse compute and increasing overall pipeline latency. Hub models with high fanout should be persisted as tables or incremental models so that downstream builds read pre-computed results rather than re-running the same transformations repeatedly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
materializations
|
list[str] | None
|
Accepted durable materializations for models above the fanout threshold. |
None
|
min_downstream_models
|
int | None
|
The minimum number of downstream models that triggers this check. |
3
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
models |
list[ModelNode]
|
List of ModelNode 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_materialization_by_fanout
min_downstream_models: 5
materializations:
- incremental
- table
Source code in src/dbt_bouncer/checks/manifest/models/lineage.py
check_model_max_chained_views
#
Models cannot have more than the specified number of upstream dependents that are not tables.
Rationale
Long chains of views and ephemeral models force the data warehouse to execute deeply nested queries at read time, which degrades query performance and can hit platform-specific nesting limits. Capping chained views encourages materialising intermediate results, trading a small amount of storage for significantly faster query execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
materializations_to_include
|
list[str] | None
|
List of materializations to include in the check. |
['ephemeral', 'view']
|
max_chained_views
|
int | None
|
The maximum number of upstream dependents that are not tables. |
3
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
models |
list[ModelNode]
|
List of ModelNode 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_max_chained_views
materializations_to_include:
- ephemeral
- my_custom_materialization
- view
max_chained_views: 5
Source code in src/dbt_bouncer/checks/manifest/models/lineage.py
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 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | |
check_model_max_fanout
#
Models cannot have more than the specified number of downstream models.
Rationale
A model with many direct downstream dependents becomes a high-impact change point — any modification to it requires testing and potentially breaking many consumers. Capping fanout encourages breaking widely-shared logic into more focused intermediate models, reducing the blast radius of changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_downstream_models
|
int | None
|
The maximum number of permitted downstream models. |
3
|
Receives at execution time:
| Name | Type | Description |
|---|---|---|
model |
ModelNode
|
The ModelNode object to check. |
models |
list[ModelNode]
|
List of ModelNode 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):
Source code in src/dbt_bouncer/checks/manifest/models/lineage.py
check_model_max_upstream_dependencies
#
Limit the number of upstream dependencies a model has.
Rationale
A model that depends on too many upstream models, sources, or macros is likely doing too much in one place. Limiting upstream dependencies encourages splitting large transformations into smaller, testable units, which improves build times, reduces coupling, and makes the DAG easier to reason about.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_upstream_macros
|
int | None
|
The maximum number of permitted upstream macros. |
5
|
max_upstream_models
|
int | None
|
The maximum number of permitted upstream models. |
5
|
max_upstream_sources
|
int | None
|
The maximum number of permitted upstream sources. |
1
|
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):