Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to var, global macro resolution rules for package resources #3605

Merged
merged 5 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions website/docs/docs/build/custom-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ The default implementation of `generate_alias_name` simply uses the supplied `al

</VersionBlock>

<VersionBlock firstVersion="1.6">

### Managing different behaviors across packages

See docs on macro `dispatch`: ["Managing different global overrides across packages"](/reference/dbt-jinja-functions/dispatch)

</VersionBlock>

### Caveats

#### Ambiguous database identifiers
Expand Down
8 changes: 8 additions & 0 deletions website/docs/docs/build/custom-databases.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ The default implementation of `generate_database_name` simply uses the supplied

</File>

<VersionBlock firstVersion="1.6">

### Managing different behaviors across packages

See docs on macro `dispatch`: ["Managing different global overrides across packages"](/reference/dbt-jinja-functions/dispatch)

</VersionBlock>

## Considerations

### BigQuery
Expand Down
10 changes: 9 additions & 1 deletion website/docs/docs/build/custom-schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ The following context methods _are_ available in the `generate_schema_name` macr
| Other macros in your project | Macro | ✅ |
| Other macros in your packages | Macro | ✅ |

#### Which vars are available in generate_schema_name?
### Which vars are available in generate_schema_name?

<Changelog>

Expand All @@ -190,6 +190,14 @@ for more information on these changes.
Globally-scoped variables and variables defined on the command line with
[--vars](/docs/build/project-variables) are accessible in the `generate_schema_name` context.

<VersionBlock firstVersion="1.6">

### Managing different behaviors across packages

See docs on macro `dispatch`: ["Managing different global overrides across packages"](/reference/dbt-jinja-functions/dispatch)

</VersionBlock>

## Managing environments

In the `generate_schema_name` macro examples shown above, the `target.name` context variable is used to change the schema name that dbt generates for models. If the `generate_schema_name` macro in your project uses the `target.name` context variable, you must additionally ensure that your different dbt environments are configured appropriately. While you can use any naming scheme you'd like, we typically recommend:
Expand Down
24 changes: 19 additions & 5 deletions website/docs/docs/build/project-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,32 @@ You can find more information on defining dictionaries with YAML [here](https://

### Variable precedence

Variables defined with the `--vars` command line argument override variables
defined in the `dbt_project.yml` file. They are globally scoped and will be
accessible to all packages included in the project.
Variables defined with the `--vars` command line argument override variables defined in the `dbt_project.yml` file. They are globally scoped and accessible to the root project and all installed packages.

The order of precedence for variable declaration is as follows (highest priority first):

<VersionBlock firstVersion="1.6">

1. The variables defined on the command line with `--vars`.
3. The package-scoped variable declaration in the `dbt_project.yml` file
2. The global variable declaration in the `dbt_project.yml` file.
2. The package-scoped variable declaration in the root `dbt_project.yml` file
3. The global variable declaration in the root `dbt_project.yml` file
4. If this node is defined in a package: variable declarations in that package's `dbt_project.yml` file
5. The variable's default argument (if one is provided)

</VersionBlock>

<VersionBlock lastVersion="1.5">

1. The variables defined on the command line with `--vars`.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved
2. The package-scoped variable declaration in the root `dbt_project.yml` file
3. The global variable declaration in the root `dbt_project.yml` file.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved
4. The variable's default argument (if one is provided).

</VersionBlock>

If dbt is unable to find a definition for a variable after checking these four places, then a compilation error will be raised.

**Note:** Variable scope is based on the node ultimately using that variable. Imagine the case where a model defined in the root project is calling a macro defined in an installed package. That macro, in turn, uses the value of a variable. The variable will be resolved based on the _root project's_ scope, rather than the package's scope.

<Snippet src="discourse-help-feed-header" />
<DiscourseHelpFeed tags="variables"/>
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ dbt Labs is committed to providing backward compatibility for all versions 1.x,

### Quick hits

**Coming Soon**
More consistency and flexibility around packages! Resources defined in a package will respect variable and global macro definitions within the scope of that package.
- `vars` defined in a package's `dbt_project.yml` are now available in the resolution order when compiling nodes in that package, though CLI `--vars` and the root project's `vars` will still take precedence. See ["Variable Precedence"](/docs/build/project-variables#variable-precedence) for details.
- `generate_x_name` macros (defining custom rules for database, schema, alias naming) follow the same pattern as other "global" macros for package-scoped overrides. See [macro dispatch](/reference/dbt-jinja-functions/dispatch) for an overview of the patterns that are possible.
18 changes: 18 additions & 0 deletions website/docs/reference/dbt-jinja-functions/dispatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,24 @@ dispatch:

</File>

### Managing different global overrides across packages

You can override global behaviors in different ways for each project that is installed as a package. This holds true for all global macros: `generate_schema_name`, `create_table_as`, etc. When parsing or running a resource defined in a package, the definition of the global macro within that package takes precedence over the definition in the root project, because it's more specific to those resources.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

By combining package-level overrides and `dispatch`, it is possible to achieve three different patterns:

1. **Package always wins.** As the developer of dbt models in a project that will be deployed elsewhere as a package, I want full control over the macros used to define & materialize my models. My macros should always take precedence for my models, and there should not be any way to override them.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

_Mechanism:_ Each project/package fully overrides the macro by its name, e.g. `generate_schema_name` or `create_table_as`. Do not use dispatch.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

2. **Conditional application (root project wins).** As the maintainer of one dbt project in a mesh of multiple, my team wants conditional application of these rules. When running my project standalone (in development), I want my to apply my custom behavior; but when installed as a package and deployed alongside several other projects (in production), I want the root-level project's rules to apply.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

_Mechanism:_ Each package implements its "local" override by registering a candidate for dispatch with an adapter prefix, e.g. `default__generate_schema_name` or `default__create_table_as`. Then, the root-level project can register its own candidate for dispatch (`default__generate_schema_name`), winning the default search order, or by explicitly overriding the macro by name (`generate_schema_name`).
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

3. **Same rules everywhere all the time.** As a member of the data platform team responsible for consistency across teams at my organization, I want to create a "macro package" that every team can install & use.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

_Mechanism:_ Create a standalone package of candidate macros only, e.g. `default__generate_schema_name` or `default__create_table_as`. Add a [project-level `dispatch` configuration](/reference/project-configs/dispatch-config) in every project's `dbt_project.yml`.
matthewshaver marked this conversation as resolved.
Show resolved Hide resolved

## For adapter plugin maintainers

Most packages were initially designed to work on the four original dbt adapters. By using the `dispatch` macro and project config, it is possible to "shim" existing packages to work on other adapters, by way of third-party compatibility packages.
Expand Down