Getting Started
How to run dbt-bouncer
#
-
Generate dbt artifacts by running a dbt command:
dbt parse
to generate amanifest.json
artifact (no database connection required!).dbt docs generate
to generate acatalog.json
artifact (necessary if you are using catalog checks).dbt run
(or any other command that implies it e.g.dbt build
) to generate arun_results.json
artifact (necessary if you are using run results checks).
-
Create a
dbt-bouncer.yml
config file, details here. -
Run
dbt-bouncer
to validate that your conventions are being maintained.
Installing with Python#
Install from pypi.org:
Run:
dbt-bouncer
also supports a verbose mode, run:
Running dbt-bouncer (X.X.X)...
config_file=PosixPath('dbt-bouncer-example.yml')
config_file_source='COMMANDLINE'
Config file passed via command line: dbt-bouncer-example.yml
Loading config from /home/pslattery/repos/dbt-bouncer/dbt-bouncer-example.yml...
Loading config from dbt-bouncer-example.yml...
Loaded config from dbt-bouncer-example.yml...
conf={'dbt_artifacts_dir': 'dbt_project/target', 'catalog_checks': [{'name': 'check_column_name_complies_to_column_type', 'column_name_pattern': '^is_.*', 'exclude': '^staging', 'types': ['BOOLEAN']}]}
Validating conf...
Running as an executable using uv#
Run dbt-bouncer
as a standalone Python executable using uv
:
GitHub Actions#
Run dbt-bouncer
as part of your CI pipeline:
name: CI pipeline
on:
pull_request:
branches:
- main
jobs:
run-dbt-bouncer:
permissions:
pull-requests: write # Required to write a comment on the PR
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate or fetch dbt artifacts
run: ...
- uses: godatadriven/dbt-bouncer@vX.X
with:
config-file: ./<PATH_TO_CONFIG_FILE>
output-file: results.json # optional, default does not save a results file
send-pr-comment: true # optional, defaults to true
show-all-failures: false # optional, defaults to false
verbose: false # optional, defaults to false
We recommend pinning both a major and minor version number.
Docker#
Run dbt-bouncer
via Docker:
docker run --rm \
--volume "$PWD":/app \
ghcr.io/godatadriven/dbt-bouncer:vX.X.X \
--config-file /app/<PATH_TO_CONFIG_FILE>
Pex#
You can also run the .pex
(Python EXecutable) artifact directly once you have a python executable (3.9 -> 3.13) installed:
wget https://github.com/godatadriven/dbt-bouncer/releases/download/vX.X.X/dbt-bouncer.pex -O dbt-bouncer.pex
python dbt-bouncer.pex --config-file $PWD/<PATH_TO_CONFIG_FILE>
How to contribute a check to dbt-bouncer
#
See Adding a new check.
How to add a custom check to dbt-bouncer
#
In addition to the checks built into dbt-bouncer
, the ability to add custom checks is supported. This allows users to write checks that are specific to the conventions of their projects. To add a custom check:
- Create an empty directory and add a
custom_checks_dir
key to your config file. The value of this key should be the path to the directory you just created, relative to where the config file is located. - In this directory create an empty
__init__.py
file. - In this directory create a subdirectory named
catalog
,manifest
orrun_results
depending on the type of artifact you want to check. -
In this subdirectory create a python file that defines a check. The check must meet the following criteria:
- Start with "Check".
- Inherit from dbt_bouncer.check_base.BaseCheck.
- Have a name attribute that is a string whose value is the snake case equivalent of the class name.
- A default value provided for optional input arguments and arguments that are received at execution time.
- Have a doc string that includes a description of the check, a list of possible input parameters and at least one example.
- A clear message in the event of a failure.
-
In your config file, add the name of the check and any desired arguments.
- Run
dbt-bouncer
, your custom check will be executed.
An example:
-
Directory tree:
-
Contents of
check_custom_to_me.py
:from typing import TYPE_CHECKING, Literal from pydantic import Field from dbt_bouncer.check_base import BaseCheck if TYPE_CHECKING: import warnings with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) from dbt_bouncer.parsers import DbtBouncerModelBase class CheckModelDepcrecationDate(BaseCheck): model: "DbtBouncerModelBase" = Field(default=None) name: Literal["check_model_deprecation_date"] def execute(self) -> None: """Execute the check.""" assert self.model.deprecation_date is not None, f"`{self.model.name}` requires a `deprecation_date` to be set."
-
Contents of
dbt-bouncer.yml
: