DBT中如何将config里配置的嵌套dict payload传递给宏使用
问题根源
dbt的模型配置config会自动将嵌套字典这类非基础类型的参数序列化为JSON字符串存储,你直接通过config.get('payload')获取到的是字符串类型的值,自然没有字典的get方法,所以触发了报错。
解决方案
只需要在使用payload前用Jinja内置的fromjson过滤器将JSON字符串反序列化为字典即可,有两种修改方式可选:
方式1:修改宏内部逻辑(更通用,无需调整调用方代码)
直接在宏内部对入参做统一反序列化处理,所有调用方都不需要改动:
-- macros/test_payload.sql {% macro test_payload(payload=config.get('payload')) -%} {# 反序列化payload为字典,空值场景可自行加判断兼容 #} {% set payload = payload | fromjson %} {% for input, params in payload.get('inputs').items() %} -- {{loop.index }}: {{input}}, {{params}} {% endfor %} {% endmacro %}
修改后原来的model_1.sql无需调整即可正常编译运行,输出结果和直接传字典的效果完全一致。
方式2:调用宏时手动转换
如果不想修改宏的代码,也可以在调用时对从config取出的payload做转换:
-- model_1.sql {{ config( payload = { 'inputs': { 'input1': {'param1': false, 'param2': 'test'}, 'input2': {'param1': false, 'param2': 'test'}, }, 'other_params': { 'interval': 1, 'unit': 'hour', } } ) }} -- 调用时先转字典 {{ test_payload(config.get('payload')|fromjson) }}
补充说明
如果你的payload可能为空,建议加一层非空判断避免反序列化报错,示例如下:
{% set payload = payload | fromjson if payload is not none else {} %}
内容的提问来源于stack exchange,提问作者modulus0
相关产品推荐
相关产品推荐

