Problem
I would like to pass a nested dict-of-dicts payload from a model's config to be used in a macro for processing. The payload should be a dictionary with an arbitrary number of keys, and parameters for each of these keys, e.g.:
{{ config(
payload = {
'inputs': {
'input1': {'param1': false, 'param2': 'test'},
'input2': {'param1': false, 'param2': 'test'},
},
'other_params': {
'interval': 1,
'unit': 'hour',
}
})
}}
However I am encountering an error in passing nested dictionary args in the config variable to a macro that uses the payload.
When I try to access the items in the input payload, with e.g. payload.get('inputs'), I get the following error:
Running with dbt=0.20.0
Encountered an error:
Compilation Error in model tf_sample (models/intermediate/development/tf_sample.sql)
'str object' has no attribute 'get'
> in macro test_payload (macros/test_payload.sql)
> called by model tf_sample (models/intermediate/development/tf_sample.sql
However, I believe this issue is specific to how the config variables are being handled, because if I pass the payload dict into the macro directly, the macro will parse successfully.
Question
How can I create a payload dict in this format to be passed to a macro?
Minimal Working Example of the Problem
Below I have created a MWE to demonstrate the issue:
Example macro: loop over the provided payload.get('inputs')
-- macros/test_payload.sql
{% macro test_payload(payload=config.get('payload')) -%}
{% for input, params in payload.get('inputs').items() %}
-- {{loop.index }}: {{input}}, {{params}}
{% endfor %}
{% endmacro %}
~
However this macro will not succeed to pull in the config.get('payload') in the way that I am expecting:
Example model calling test_payload() -- this will FAIL to parse
The below SQL calls the macro in the way I would like (and would expect to work):
-- model_1.sql --- This will FAIL to parse
{{
config(
payload = {
'inputs': {
'input1': {'param1': false, 'param2': 'test'},
'input2': {'param1': false, 'param2': 'test'},
},
'other_params': {
'interval': 1,
'unit': 'hour',
}
}
)
}}
-- this fails
{{ test_payload(config.get('payload')) }}
-- this also fails
{{ test_payload() }}
Example model calling test_payload() with an embedded dict; SUCCEEDS
However if I pass the payload in directly to the macro test_payload, I successfully get the expected output:
-- model_2.sql --- This will SUCCEED! But it doesn't store the payload in the config :(
{{ test_payload(payload={
'inputs': {
'input1': {'param1': false, 'param2': 'test'},
'input2': {'param1': false, 'param2': 'test'},
},
'other_params': {
'interval': 1,
'unit': 'hour',
}
}) }}
Result:
-- 1: input1, {'param1': False, 'param2': 'test'}
-- 2: input2, {'param1': False, 'param2': 'test'}