Migrating to dbt-bouncer v3.0.0#
dbt-bouncer v3.0.0 is a major release with significant internal improvements. This guide covers what changed and what you need to do to upgrade.
Who needs to do what#
| You are... | Action required |
|---|---|
Using dbt-bouncer.yml config only |
Minimal — review config changes |
Writing custom checks (subclassing BaseCheck) |
Must migrate — see custom check migration |
Importing dbt-bouncer as a Python library |
Review — see API changes |
| Using dbt-bouncer GitHub Action | No changes required (action updated internally) |
Configuration changes#
Your config files still work#
Existing dbt-bouncer.yml and pyproject.toml [tool.dbt-bouncer] configurations are fully compatible. Check names and parameters are unchanged.
Config validation is now strict#
Two changes that may surface pre-existing issues in your config:
- Check name validation: Misspelled check names in your config (e.g.
check_modle_accessinstead ofcheck_model_access) now produce an error instead of being silently ignored. - Config parse errors: Previously, some config file parsing errors were silently swallowed. They now produce clear error messages with line numbers.
If your config was working correctly before, no action is needed.
New: dbt-bouncer.toml support#
You can now use dbt-bouncer.toml as an alternative config format alongside YAML.
CLI changes#
New run subcommand#
The default behaviour (running checks) is now also available as an explicit run subcommand. Both work:
# These are equivalent:
dbt-bouncer --config-file dbt-bouncer.yml
dbt-bouncer run --config-file dbt-bouncer.yml
New CLI features#
dbt-bouncer list --output-format json— machine-readable check listingdbt-bouncer run --dry-run— preview which checks would run without executing them- Rich-formatted table output for artifact parsing and results
Click → Typer#
The CLI framework changed from Click to Typer. If you were relying on Click-specific behaviour in wrapper scripts, review the Typer docs. The command-line interface is otherwise the same.
One notable difference: boolean flags now use --flag / --no-flag syntax instead of --flag true/false:
The GitHub Action handles this automatically — no changes needed if you use the action.
Dependency changes#
Removed dependencies#
The following are no longer installed with dbt-bouncer. If you relied on them transitively, add them to your own requirements.txt:
| Removed | Replacement |
|---|---|
click |
typer (included) |
dbt-artifacts-parser |
Internal parser (no action needed) |
progress |
rich (included) |
requests |
Not needed |
tabulate |
rich (included) |
New dependencies#
| Package | Version |
|---|---|
typer |
>=0.12, <1 |
rich |
>=13, <15 |
orjson |
>=3, <4 |
Python API changes#
Import path changes#
# v2.x
from dbt_bouncer.resource_type import ResourceType
# v3.0.0
from dbt_bouncer import ResourceType
# or
from dbt_bouncer.enums import ResourceType
The dbt_bouncer.resource_type module no longer exists.
New exports#
from dbt_bouncer import (
CheckOutcome, # FAILED, SUCCESS
CheckSeverity, # ERROR, WARN
ConfigFileName, # DBT_BOUNCER_TOML, DBT_BOUNCER_YML, PYPROJECT_TOML
Materialization, # EPHEMERAL, INCREMENTAL, TABLE, VIEW
ResourceType,
run_bouncer,
)
Module structure changes#
| v2.x | v3.0.0 |
|---|---|
dbt_bouncer.resource_type |
Removed → dbt_bouncer.enums |
checks/manifest/check_models.py |
Split into checks/manifest/models/{access,code,columns,...}.py |
checks/manifest/check_sources.py |
Split into checks/manifest/sources/ subpackage |
checks/manifest/check_columns.py |
Split into checks/manifest/columns/ subpackage |
| — | dbt_bouncer.check_decorator (new) |
| — | dbt_bouncer.testing (new) |
| — | dbt_bouncer.enums (new) |
Migrating custom checks#
v2.x: Class-based checks#
from dbt_bouncer.checks.common import BaseCheck
class CheckModelAccess(BaseCheck):
access: Literal["private", "protected", "public"]
model: DbtBouncerModelBase | None = Field(default=None)
name: Literal["check_model_access"]
def execute(self) -> None:
assert self.model is not None
if self.model.access.value != self.access:
raise DbtBouncerFailedCheckError(
f"Model `{self.model.name}` has access `{self.model.access.value}`, expected `{self.access}`."
)
v3.0.0: Decorator-based checks#
from dbt_bouncer.check_decorator import check, fail
@check
def check_model_access(model, *, access: str):
"""Each model should have the specified access level."""
if model.access and model.access.value != access:
fail(
f"Model `{model.name}` has access `{model.access.value}`, expected `{access}`."
)
Key differences:
- No class inheritance — use the
@checkdecorator on a function - No
execute()method — the function body is the check logic - No
namefield — inferred from the function name - No
iterate_overClassVar — inferred from the first parameter name (e.g.model→ iterates over models) fail()instead of raising exceptions — callfail("message")to report failures- Parameters are keyword-only — use
*separator after the resource parameter
Plugin registration#
Custom check packages must now register via entry points:
# pyproject.toml of your custom checks package
[project.entry-points."dbt_bouncer.checks"]
my_checks = "my_package.checks"
Testing custom checks#
from dbt_bouncer.testing import check_fails, check_passes
def test_check_model_access_pass():
check_passes(
check_model_access,
model={"name": "my_model", "access": {"value": "private"}},
access="private",
)
def test_check_model_access_fail():
check_fails(
check_model_access,
model={"name": "my_model", "access": {"value": "public"}},
access="private",
)
New checks in v3.0.0#
The following checks are new in this release:
check_model_columns_have_relationship_tests— verify columns have relationship testscheck_model_hard_coded_references— detect hard-coded references in model SQLcheck_seed_column_types— validate seed column typescheck_seed_has_unit_tests— verify seeds have unit testscheck_snapshot_description_populated— require snapshot descriptionscheck_test_has_meta_keys— require specific meta keys on tests
New features#
- JSON Schema for config files — enables IDE autocomplete and validation
dbt-bouncer.tomlconfig format support--dry-runflag — preview checks without running themlist --output-format json— machine-readable output- Entry-points plugin system — third-party check packages
- Rich table output — improved terminal formatting
Getting help#
If you run into issues upgrading:
- Check that your config file has no misspelled check names
- Update custom check imports per the table above
- Open an issue at github.com/godatadriven/dbt-bouncer/issues