Let's try: dbt part 9 - variables
Variables bring flexibility to our pipelines so we define and utilize them here.
Variables bring flexibility to our pipelines. There are two easy methods to define and utilize variables in dbt.
Set globally
We can declare and define through dbt_project.yml as below.
Define and use
Config in dbt_project.yml can be made under the key vars like this.
1
2
vars:
target_date: 2026-01-01
This is the new variable target_date and then we can refer the variable target_date using var() macro in a model like below.
1
2
3
select *
from {{ source("students", "student_grades") }}
where updated_at = '{{ var("target_date") }}'
When we compile and the value of target_date would be assigned for updated_at like this.
1
2
3
4
5
$ dbt compile
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where updated_at = '2026-01-01'
Overriding
There is a case we want to override the variables’ value so with --vars flag the values will be substituted.
1
2
3
4
5
$ dbt compile --vars '{target_date: 2026-02-01}'
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where updated_at = '2026-02-01'
Double-check the quotes and escape characters for the YAML configs and flag
--vars.
Default value
In some cases, we need default values for variables. Supplying second argument to var() macro is giving default values.
1
2
3
4
5
select *
from {{ source("students", "student_grades") }}
where
updated_at = '{{ var("target_date") }}'
and name = '{{ var("target_name", "Billy") }}'
Now Billy is a default value when target_name can’t be found like this.
1
2
3
4
5
6
7
8
$ dbt compile
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where
updated_at = '2026-01-01'
and name = 'Billy'
Dealing with arrays
We can define an array in YAML syntax using hyphens (-) or brackets ([]) as below.
1
2
3
4
5
6
7
vars:
target_date: 2026-01-01
target_subjects:
- "biology"
- "physics"
- "chemistry"
other_subjects: ["literature", "mathematics"]
Now let’s say we want this final query below as a model.
1
2
3
4
5
6
7
$ dbt compile
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where
updated_at = '2026-01-01'
and subject in ('biology', 'physics', 'chemistry')
There are different ways to achieve it.
We can do it in traditional loop way. With iterating over an array using for-loop, concatenating each element in it with comma
,if the element isn’t the last in the array, and we can explicitly get a complete string having commas from that array.1 2 3 4 5 6 7 8 9
select * from {{ source("students", "student_grades") }} where updated_at = '{{ var("target_date") }}' and subject in ( {%- for subject in var("target_subjects") -%} '{{ subject }}' {%- if not loop.last -%},{%- endif -%} {%- endfor -%} )
By default, an array can be cast to a string in format
[a, b, c, ...], so we can just using Jinja filterreplaceto transform[]to().1 2 3 4 5
select * from {{ source("students", "student_grades") }} where updated_at = '{{ var("target_date") }}' and subject in {{ var("target_subjects") | replace("[", "(") | replace("]", ")") }}
Or just a Jinja filter
jointo combine all elements with commas and surround them with quotes and parentheses('...')then we now get a complete string.1 2 3 4 5
select * from {{ source("students", "student_grades") }} where updated_at = '{{ var("target_date") }}' and subject in ('{{ var("target_subjects") | join("', '") }}')
Set locally
In case we don’t want to declare it globally but just have some to use in a single model, we can do this.
Set and use
Using {% set <variable> = <value> %} to declare a variable and its value in the model. Then refer the variables just by writing statement {{ <var> }}.
1
2
3
4
5
{%- set target_date = "2026-01-01" -%}
select *
from {{ source("students", "student_grades") }}
where updated_at = '{{ target_date }}'
Now target_date is “2026-01-01” after compiling.
1
2
3
4
5
$ dbt compile
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where updated_at = '2026-01-01'
Set arrays
Also declare arrays and concatenate it to string like above examples.
1
2
3
4
5
6
7
{%- set target_date = "2026-01-01" -%}
{%- set target_subjects = ["biology", "physics", "chemistry"] -%}
select *
from {{ source("students", "student_grades") }}
where
updated_at = '{{ target_date }}'
and subject in {{ target_subjects | replace("[", "(") | replace("]", ")") }}
Now we get the array like this.
1
2
3
4
5
6
7
$ dbt compile
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where
updated_at = '2026-01-01'
and subject in ('biology', 'physics', 'chemistry')
Overriding from global vars
And of course, defining local variables by inheriting global variables is also possible.
1
2
3
4
{%- set search_date = var("target_date") -%}
select *
from {{ source("students", "student_grades") }}
where updated_at = '{{ search_date }}'
Then --vars flag is usable here.
1
2
3
4
5
$ dbt compile --vars '{target_date: 2026-02-01}'
Compiled node 'selected_students' is:
select *
from `bluebirz-playground`.`raw`.`student_grades`
where updated_at = '2026-02-01'
Wrap up
- Define global variables with key
varsindbt_project.yml. - Utilize global variables by
{{ var("<var>", "<default_value>") }}. - Define local variables with
{% set <var> = <value> %}in a model. - Utilize local variables by
{{ <var> }}. - Flag
--varsis for overriding variables when execute dbt commands. - Jinja filters like
replace,joinand for-loop are useful for array concatenation.
