Last active
October 9, 2023 15:41
-
-
Save dah33/973c7db8fb14734f95846a9f4e647079 to your computer and use it in GitHub Desktop.
How to do partial function application in Jinja / dbt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# 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