Built-in Jinja context variables in dbt - Time & Space Complexity
We want to understand how the time it takes to run dbt models changes when using built-in Jinja context variables.
Specifically, we ask: How does accessing these variables affect execution time as input grows?
Analyze the time complexity of the following dbt code snippet.
{% for column in adapter.get_columns_in_relation(this) %}
{{ column.name }}
{% endfor %}
{{ this.schema }}
{{ this.identifier }}
This code loops over all columns in a table relation and accesses built-in Jinja context variables for schema and identifier.
Look at what repeats and what runs once.
- Primary operation: Looping over each column in the table.
- How many times: Once for every column in the table.
- Accessing
this.schemaandthis.identifierhappens only once each.
As the number of columns grows, the loop runs more times.
| Input Size (n = columns) | Approx. Operations |
|---|---|
| 10 | 10 loop steps + 2 variable accesses |
| 100 | 100 loop steps + 2 variable accesses |
| 1000 | 1000 loop steps + 2 variable accesses |
Pattern observation: The time grows roughly in direct proportion to the number of columns.
Time Complexity: O(n)
This means the time to run grows linearly with the number of columns in the table.
[X] Wrong: "Accessing built-in Jinja variables like this.schema takes time proportional to the number of columns."
[OK] Correct: These variables are simple properties accessed once, so their cost does not grow with input size.
Understanding how loops and variable accesses scale helps you write efficient dbt models and explain your code clearly in interviews.
"What if we nested another loop inside to process each column's metadata? How would the time complexity change?"
Practice
run_started_at provide in dbt?Solution
Step 1: Understand the purpose of
This variable holds the timestamp marking the start of the dbt run.run_started_atStep 2: Compare with other options
Other options describe unrelated information like model name or connection details.Final Answer:
The timestamp when the current dbt run started -> Option CQuick Check:
run_started_at= Timestamp [OK]
- Confusing run_started_at with model name
- Thinking it gives database info
- Assuming it counts models
Solution
Step 1: Recall the correct variable for current model
The variablethisrefers to the current model, andthis.namegives its name.Step 2: Check syntax correctness
Only{{ this.name }}correctly accesses the model name in Jinja syntax.Final Answer:
{{ this.name }} -> Option AQuick Check:
Current model name ={{ this.name }}[OK]
this.name for current model name [OK]- Using undefined variables like model_name
- Missing dot notation after this
- Using incorrect variable names
{{ invocation_id }}?
{% set id = invocation_id %}{{ id }}Solution
Step 1: Understand what
This variable holds a unique string ID for the current dbt run invocation.invocation_idrepresentsStep 2: Analyze the code snippet
The code setsidtoinvocation_idand then outputs it, so it prints the unique run ID.Final Answer:
A unique identifier string for the current dbt run -> Option BQuick Check:
invocation_id= Unique run ID [OK]
- Thinking it counts models
- Confusing with timestamps
- Assuming it causes an error
{{ run_started_at.strftime('%Y-%m-%d') }}. What is the likely cause?Solution
Step 1: Check the type of
In dbt,run_started_atrun_started_atis a string timestamp, not a datetime object.Step 2: Understand why
Since it's a string, callingstrftimefailsstrftime(a datetime method) causes an error.Final Answer:
run_started_at is a string, not a datetime object, so strftime fails -> Option AQuick Check:
String type blocks datetime methods [OK]
- Assuming run_started_at is datetime
- Using single braces for Jinja variables
- Thinking strftime is unsupported in Jinja
Solution
Step 1: Extract date from
Sincerun_started_atstringrun_started_atis a string like 'YYYY-MM-DDTHH:MM:SS', slicing the first 10 characters gets the date.Step 2: Use
The snippet correctly setsinvocation_idandrun_datein SELECTrun_dateand uses both variables in the SELECT statement.Step 3: Check other options for errors
{% set run_date = run_started_at.strftime('%Y-%m-%d') %} SELECT *, '{{ invocation_id }}' AS run_id, '{{ run_date }}' AS run_date FROM {{ this }} tries to usestrftimeon a string (error). SELECT *, '{{ invocation_id }}' AS run_id, '{{ run_started_at }}' AS run_date FROM {{ this }} uses full timestamp, not formatted date. {% set run_date = run_started_at.split('-')[0] %} SELECT *, '{{ invocation_id }}' AS run_id, '{{ run_date }}' AS run_date FROM {{ this }} extracts only year incorrectly.Final Answer:
Extracts date with run_started_at[:10] and uses invocation_id -> Option DQuick Check:
Slice string for date, use invocation_id [OK]
- Using strftime on string variable
- Not formatting run_started_at to date
- Extracting only year instead of full date
Ready to prove it?
Pass the test and this pattern moves unknown
