Search code examples
jinja2dbt

DBT jinja variable setting scope or order when using macro


I'm setting some variables and using a macro to define one of them. If I simply use the macro to set the variable and use this directly it is working properly. However, when I try to re-use this variable in defining another variable, I'm getting an undefined error. This is NOT the case when I replace the macro with some fixed value. Is there some (random) order of execution of this code? or is this some sort of racing condition as the macro takes time to execute?

This works

{% set step_size = 6000 %}
{% set number_of_rows = number_of_rows_to_process(ref("some_model")) %}
{{ number_of_rows }}

This also works

{% set step_size = 6000 %}
{% set number_of_rows = 12000 %}
{{ number_of_rows }}
{% set steps = ((number_of_rows + (step_size - 1)) / step_size)|round(0, 'ceil')|int %}
{{steps}}

However, this doesn't work

This throws an 'number_of_rows is undefined' error

{% set step_size = 6000 %}
{% set number_of_rows = number_of_rows_to_process(ref("some_model")) %}
{{ number_of_rows }}
{% set steps = ((number_of_rows + (step_size - 1)) / step_size)|round(0, 'ceil')|int %}
{{steps}}

The macro simply is executing a COUNT(*) on the source to get the number of rows

UPDATE: overlooked the fact that within the macro there is also a variable called number_of_rows it turns out that it's this variable that's actually undefined. So it seems somehow the macro doesn't get properly called with the reference to the model in case of re-using it in another set variable?


Solution

  • After a lot of trial and error I managed to fix the issue. It turns out the problem was within the macro and the fact I was using {% if execute %} without an else statement (as I read somewhere this wasn't needed).

    Still not sure what exactly was going on, since execute was always true and it didn't encounter a problem when using the macro's returned value directly. Only when trying to manipulate this value all of a sudden the return value would be undefined when the else block wasn't there even though execute was true