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

target-based Jinja rendering of vars in dbt_project.yml #3105

Closed
1 of 5 tasks
matt-winkler opened this issue Feb 16, 2021 · 10 comments
Closed
1 of 5 tasks

target-based Jinja rendering of vars in dbt_project.yml #3105

matt-winkler opened this issue Feb 16, 2021 · 10 comments
Labels
bug Something isn't working stale Issues that have gone stale vars

Comments

@matt-winkler
Copy link
Contributor

Describe the bug

When compiling / running models from dbt Cloud, the compiler does not correctly evaluate variables defined using jinja in dbt_project.yml and referenced in a sources: block.

Steps To Reproduce

Create in dbt_project.yml:

vars:
  database_prefix: "{% if target.name == 'dev' %}dev_{% else %}{% endif %}"

Create in sources.yml:

sources:
  - name: tpch
    database: "{{ var('database_prefix') }}raw"

Expected behavior

SQL compilation will resolve the variable to either dev_ or an empty string when running either dbt compile or dbt run

Screenshots and log output

On dbt compile:
image

System information

Which database are you using dbt with?

  • postgres
  • redshift
  • bigquery
  • snowflake
  • other (specify: ____________)

The output of dbt --version:

0.18.1

The operating system you're using:
dbt Cloud

@matt-winkler matt-winkler added bug Something isn't working triage labels Feb 16, 2021
@matt-winkler matt-winkler changed the title Unable to reference dbt_projecy.yml vars from sources Unable to reference dbt_project.yml vars from sources Feb 16, 2021
@jtcohen6 jtcohen6 removed the triage label Feb 16, 2021
@jtcohen6
Copy link
Contributor

Thanks for the bug report @matt-winkler! I get that this is unexpected behavior. The truth is that vars in dbt_project.yml aren't Jinja-rendered today. dbt needs to know the values of vars before it can render any other parts of the project. This leads to weirdness today whereby var() is in the scope of the dbt_project.yml context, but only if set by --vars (docs).

Ultimately, a solution here would be to clearly establish the parsing order of project files:

  • env vars, --vars, dbt_version, and builtins are always available
  • parse profile --> get target values
  • parse vars (with env vars, --vars, and target available)
  • parse the rest of the project file

I'm definitely interested in rationalizing when vars are available, and what's available to them: see #2955. I don't feel a ton of immediate priority here, though; in the use case you're describing, there are several other ways to achieve this env-based behavior:

  • Your deployment can override {{ var('database_prefix') }} with a (static string) value passed to --vars
  • You could control this behavior via {{ env_var() }} instead

If you do want dbt to handle the database prefixing on the basis of target.name alone, it's not possible to get any DRYer than this:

version: 2

sources:
  - name: tpch
    database: "{{ 'dev_' if target.name == 'dev' else '' }}raw"
    tables:
      - name: something

@matt-winkler
Copy link
Contributor Author

Thanks for the commentary @jtcohen6! Super helpful for you to reinforce that this relates to the parsing order. Agree that adding the jinja to sources.yml works. Thanks for linking 2995 as well. Would you still say this fits as a bug, or should we close and plan to handle with the additional variable extraction mentioned in 2955?

@jtcohen6 jtcohen6 added the vars label Feb 22, 2021
@jtcohen6
Copy link
Contributor

After thinking about it a bit more, I do think this represents something novel that hasn't been requested before, though with plenty of overlap with other questions of parse order and vars definitions. I'm going to recast this as a feature request and rename it accordingly.

Glad you're able to work around this in the meantime!

@jtcohen6 jtcohen6 changed the title Unable to reference dbt_project.yml vars from sources target-based Jinja rendering of vars in dbt_project.yml Feb 22, 2021
@adityaguru149
Copy link

adityaguru149 commented May 27, 2021

On the same boat here.
I was trying to figure out a way to get the source schema name (+some other values) to change based on the target.

Use Case:
Multiple customers have their data in separate tables having same fields. Similar transformations need to be run on them resulting in a set of resultant tables per customer which can then be utilized by BI tool.
Similar requirement on Stackoverflow

As of now how this can be achieved is kind of bundle the SQL transformations into macros and use them in tables, once for each customer. Any other approach?

Solution:
Extracting out vars makes sense . Being able to select vars per target / making target itself a var would then enable such use cases.

@jtcohen6 Thoughts?

owlas added a commit to owlas/docs.getdbt.com that referenced this issue Jul 3, 2021
Document an exception where `env_vars` is not rendered in the `vars` block of a `dbt_project.yml` file.

re: dbt-labs/dbt-core#3105 (comment)
@github-actions
Copy link
Contributor

This issue has been marked as Stale because it has been open for 180 days with no activity. If you would like the issue to remain open, please remove the stale label or comment on the issue, or it will be closed in 7 days.

@choudrybabu
Copy link

database: "{{ 'dev_' if target.name == 'dev' else '' }}raw" --> can this be changed to if else , we have 4 different targets and so 4 diff db names for each target
any suggestions

@philippefutureboy
Copy link

@choudrybabu

Either use the target.name directly:

{{ target.name + '_' if target.name else '' }}raw

or a dictionary:

{{ {"dev": "dev_", "target-2": "target_2_", ...}.get(target.name, '') }}raw

?

Could that work?

nghi-ly added a commit to dbt-labs/docs.getdbt.com that referenced this issue Jun 22, 2023
[Preview](https://deploy-preview-3554--docs-getdbt-com.netlify.app/docs/build/project-variables#defining-variables-in-dbt_projectyml)

## What are you changing in this pull request and why?

`vars` within `dbt_project.yml` does not support rendering, but it has
been requested dbt-labs/dbt-core#3105 and
dbt-labs/dbt-core#4314.

In the meantime, we want to make it clear within our docs that this
isn't supported.

See
dbt-labs/dbt-core#4314 (comment)
for context.

## 🎩 

<img width="550" alt="image"
src="https://github.com/dbt-labs/docs.getdbt.com/assets/44704949/95e6e65a-028e-4e85-8c56-c4cf12929dc7">


## Checklist
- [x] Review the [Content style
guide](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/content-style-guide.md)
and [About
versioning](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/single-sourcing-content.md#adding-a-new-version)
so my content adheres to these guidelines.
@moseleyi
Copy link

moseleyi commented Feb 6, 2024

I am so much in need of using target.project in dbt_project.yml vars! I want to create vars for couple of policy tags that have to be set up on a project level (and dev dbt goes to dev project). Right now I have to copy a long string for each column in any model:

policy_tags:
  - 'projects/{{target.project}}/locations/{{var("default_location")}}/taxonomies/6932546414257800377/policyTags/3610480920170058151'

but it would be eaiser for people writing the models to just use;

policy_tags:
  - '{{ var("full_name_policy_tag") }}'

because I could change the policy without having to change all the references

@philippefutureboy
Copy link

philippefutureboy commented Feb 6, 2024

@moseleyi Have you considered using env_var instead of var and call dbt from a parent process (python script or a workflow manager such as Airflow)? I don't know how many env vars you'll need for your use case, but it can be manageable if you think it's worth the trouble.

@moseleyi
Copy link

Not sure, would I just pass project and location? and would the vars in dbt_project.yml then work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working stale Issues that have gone stale vars
Projects
None yet
Development

No branches or pull requests

6 participants