Search code examples
jinja2dbt

Passing column divided by value as parameter in macro dbt jinja


I'd like to pass a column divided by a value as a parameter in a jinja macro.

I'm using the macro in a dbt model like this {{ pmt('rate'/1200, 'nper', 'pv', 'fv') }}

However, this gives the error message

"Encountered an error: unsupported operand type(s) for /: 'str' and 'int'"


Solution

  • Most likely you have to treat the whole argument as a string literal (quote the whole thing):

    {{ pmt('rate/1200', 'nper', 'pv', 'fv') }}
    

    The reason this works is because it is likely that the macro templates this string into SQL code, e.g.,

    {% macro pmt(arg1, arg2, arg3, arg4) %}
    ...
    select {{ arg1 }}
    ...
    {% endmacro %}
    

    In this toy example, {{ arg1 }} will take on the value {{ 'rate/1200' }}, which enters the template (unquoted) as

    ...
    select rate/1200
    ...
    

    which is valid sql (if you have a field called rate).

    It's possible this won't work with all macros, though! In dbt, since the macros are typically templating SQL code, you usually want to pass in arguments that contain field or table references as string literals. However, the argument to the macro could stay inside the jinja context, in which case, you'll need to keep the argument unquoted, or modify a variable before it's passed into the jinja macro. As another toy example:

    {% macro print_value(val) %}
    {{ log(val, info=True) }}
    {% endmacro %}
    
    -- if val is a string literal:
    {{ print_value('rate/1200') }}
    -- $ rate/1200
    
    -- if val is unquoted:
    {% set rate = 2400 %}
    {{ print_value(rate/1200) }}
    -- $ 2