dbt Variables in Jinja
Variables in dbt let you pass values into your models at run time without hardcoding them in SQL. You define variables in configuration files or pass them on the command line. Your models read them using the var() function. Variables make models flexible and reusable across different time ranges, environments, and scenarios.
Defining Variables in dbt_project.yml
The most common place to define project-wide variables is dbt_project.yml:
# dbt_project.yml vars: start_date: '2024-01-01' end_date: '2024-12-31' minimum_order_amount: 10 exclude_test_accounts: true
Using Variables in Models
Use the var() function inside any model, macro, or test to read a variable value:
-- models/fct_orders.sql
select
order_id,
order_date,
amount_dollars
from {{ ref('stg_orders') }}
where order_date between '{{ var("start_date") }}' and '{{ var("end_date") }}'
and amount_dollars >= {{ var("minimum_order_amount") }}
{% if var("exclude_test_accounts") %}
and customer_id not in (select customer_id from {{ ref('test_accounts') }})
{% endif %}Providing a Default Value
The second argument to var() is a default value used when the variable is not defined:
{{ var('start_date', '2020-01-01') }}
-- Returns '2020-01-01' if start_date is not set anywhereOverriding Variables at Run Time
Pass variables on the command line using the --vars flag. Command-line variables override values in dbt_project.yml:
# Single variable
dbt run --vars '{"start_date": "2025-01-01"}'
# Multiple variables
dbt run --vars '{"start_date": "2025-01-01", "end_date": "2025-03-31", "minimum_order_amount": 50}'Variable Priority Order
Highest priority → command-line --vars flag → dbt_project.yml vars section Lowest priority → var() default value (second argument)
Practical Use Case: Date-Partitioned Backfill
Suppose you need to reprocess orders for a specific month. Without variables, you modify the SQL file, run it, then revert the change. With variables:
-- models/fct_monthly_revenue.sql
{{ config(materialized='table') }}
select
date_trunc('month', order_date) as revenue_month,
sum(amount_dollars) as total_revenue,
count(distinct order_id) as order_count
from {{ ref('stg_orders') }}
where order_date between '{{ var("start_date") }}' and '{{ var("end_date") }}'
group by 1# Normal monthly run (uses dbt_project.yml defaults)
dbt run --select fct_monthly_revenue
# Backfill March 2024 specifically
dbt run --select fct_monthly_revenue \
--vars '{"start_date": "2024-03-01", "end_date": "2024-03-31"}'Environment-Specific Variables
Variables can hold different values per environment target. Define them nested under target names:
# dbt_project.yml vars: # These apply to all targets minimum_order_amount: 10 # In profiles.yml, use target name to switch behavior # Then in models read target.name:
-- In a model
{% if target.name == 'prod' %}
where is_test_account = false
{% endif %}Using Variables in Macros
-- macros/get_date_filter.sql
{% macro get_date_filter() %}
order_date between '{{ var("start_date") }}' and '{{ var("end_date") }}'
{% endmacro %}-- In any model
select * from {{ ref('stg_orders') }}
where {{ get_date_filter() }}Variable Naming Conventions
Good variable names: start_date ← snake_case, descriptive minimum_order_value ← clear meaning exclude_cancelled ← boolean names start with is_ or exclude_/include_ Avoid: dt ← too short var1 ← meaningless StartDate ← inconsistent casing
Common Variable Patterns
Pattern Example ----------- ------- Date window start_date, end_date Threshold value min_revenue, max_rows Feature flag enable_new_logic: true/false Environment flag is_dev: true/false List of values excluded_regions: ['APAC', 'EMEA']
