DBT宏问题:source函数生成Relation传入union_relations失败
解决DBT宏合并Snowflake表时source函数执行失败的问题
问题根源
source()函数依赖dbt预定义的数据源配置(如sources.yml文件),你通过INFORMATION_SCHEMA动态获取的GEN开头表并未在配置中声明,因此调用source()会触发「找不到数据源」的错误。
替代方案:动态构造Relation对象
改用dbt_utils.get_relation()直接生成Relation,无需预先配置数据源。以下是完整可运行的宏代码:
{% macro union_gen_audit_tables() %} -- 第一步:查询获取所有GEN开头的表名 {% set get_tables_query %} SELECT table_name FROM X_DEV.X__AUDIT.INFORMATION_SCHEMA.TABLES WHERE table_name LIKE 'GEN%' AND table_type = 'BASE TABLE' {% endset %} {% set results = run_query(get_tables_query) %} {% if execute %} {% set table_names = results.columns[0].values() %} {% set relations = [] %} -- 第二步:循环构造每个表的Relation对象 {% for table_name in table_names %} {% set rel = dbt_utils.get_relation( database='X_DEV', schema='X__AUDIT', identifier=table_name ) %} {% if rel %} {% do relations.append(rel) %} {% else %} {{ log("Warning: 表 " ~ table_name ~ " 不存在或无访问权限", info=True) }} {% endif %} {% endfor %} -- 第三步:合并所有有效Relation {% if relations | length > 0 %} {{ dbt_utils.union_relations(relations=relations) }} {% else %} {{ log("X_DEV.X__AUDIT下未找到GEN开头的表", info=True) }} SELECT 1 AS dummy_column WHERE 1=0 -- 返回空结果集避免宏执行失败 {% endif %} {% else %} -- 干运行模式下返回空查询,防止报错 SELECT 1 AS dummy_column WHERE 1=0 {% endif %} {% endmacro %}
关键细节说明
dbt_utils.get_relation():直接通过数据库名、模式名、表名构造Relation对象,绕过source的预配置要求。execute判断:区分运行与干运行模式,干运行时不执行实际查询,避免不必要的报错。- 空结果处理:当无匹配表时返回空查询,保证宏能正常执行完成。
- 日志输出:添加警告日志,便于快速排查不存在或权限不足的表。
额外注意事项
- 确保当前dbt执行角色对
X_DEV.X__AUDIT下的所有GEN表拥有读权限。 - 如果各表结构不一致,
dbt_utils.union_relations会自动按列名对齐,但需注意数据类型的兼容性。
内容的提问来源于stack exchange,提问作者Neha Rastogi
相关产品推荐
相关产品推荐

