Skip to content

Instantly share code, notes, and snippets.

@dah33
Last active October 9, 2023 15:41
Show Gist options
  • Save dah33/973c7db8fb14734f95846a9f4e647079 to your computer and use it in GitHub Desktop.
Save dah33/973c7db8fb14734f95846a9f4e647079 to your computer and use it in GitHub Desktop.
How to do partial function application in Jinja / dbt
{# Modelled after Python's functools.partial #}
{% macro make_partial(func) %}
{% set partial = dict(func=func, args=varargs, keywords=kwargs) %}
{% do return(partial) %}
{% endmacro %}
{% macro is_partial(partial) %}
{% do return(partial is mapping
and partial.func
and partial.args
and partial.keywords) %}
{%- endmacro %}
{% macro call_partial(partial) %}
{%- set all_varargs = partial.args + varargs -%}
{%- set all_kwargs = dict(partial.keywords, **kwargs) -%}
{% do return(partial.func(*all_varargs, **all_kwargs)) %}
{%- endmacro %}
{# Prints varargs then kwargs, for testing partial #}
{% macro print_args() %}
{%- for v in varargs -%}
{{ v }}{% if not loop.last or kwargs %},{% endif %}
{%- endfor -%}
{%- for k, v in kwargs.items() -%}
{{ k }}={{ v }}{% if not loop.last %},{% endif %}
{%- endfor -%}
{% endmacro %}
{# Example, within a dbt model: #}
{% set print_poem = make_partial(print_args, 1, buckle=None) %}
{# print_poem = print_args(1, ..., buckle=None, ...) #}
select '{{ call_partial(print_poem, 2, buckle="my shoe") }}'
{# print_poem(2, buckle="my shoe") => print_args(1, 2, buckle="my shoe") #}
{# Ouputs: select '1,2,buckle=my shoe' #}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment