dbt中使用star宏时如何获取列名及对应列数据类型(Snowflake)
问题说明
在dbt中使用star宏时,默认仅返回格式化后的列名字符串,不携带字段数据类型等元数据,无法直接实现按列类型条件应用聚合函数的逻辑,以下是Snowflake环境下的可行方案。
解决方案
不要直接依赖star宏返回列名,改用dbt内置的适配器方法adapter.get_columns_in_relation()直接从Snowflake拉取目标表的完整列元数据,每个列对象会包含列名、数据类型等属性,完全满足类型判断需求。
具体实现步骤
- 先获取目标表的全量列元数据,过滤掉不需要的字段
{# 先定义目标表关系对象 #} {% set target_relation = ref('my_table_name') %} {# 拉取表的所有列元数据 #} {% set all_table_columns = adapter.get_columns_in_relation(target_relation) %} {# 过滤掉需要排除的a、b、c三列,和原star宏的except参数逻辑一致 #} {% set valid_columns = all_table_columns | rejectattr('name', 'in', ['a', 'b', 'c']) | list %} - 遍历列对象时,直接通过
data_type属性判断字段类型,按需求写聚合逻辑
布尔类型在Snowflake返回的data_type值为BOOLEAN,判断时统一转小写避免大小写差异导致的匹配失败,完整SQL代码如下:select date_trunc('week', day) as week, name, {%- for col in valid_columns %} {% if col.data_type | lower == 'boolean' %} max({{ col.name | lower }}) as {{ col.name | lower }}{%- if not loop.last %},{{ '\n ' }}{% endif %} {% endif %} {%- endfor %} from {{ ref('my_table_name') }} group by 1, 2
补充说明
- 如果需要对其他类型字段做处理,直接增加判断分支即可。Snowflake常见数值类型返回的
data_type值包括NUMBER、FLOAT、INTEGER、DECIMAL等,字符串类型为VARCHAR、TEXT,日期类型为DATE、TIMESTAMP_NTZ等。 - 如果不确定对应字段返回的类型值,可以在循环中临时加调试代码打印类型:
{% do log("列名:" ~ col.name ~ ",类型:" ~ col.data_type, info=True) %},执行dbt run时会在控制台输出所有列的实际类型值,避免匹配错误。 - 如果需要复用
star宏自带的列名转义、别名添加等能力,可以先从元数据中提取列名列表传入star宏的columns参数,不过当前按类型聚合的场景下直接遍历元数据对象更简洁。
内容的提问来源于stack exchange,提问作者brienna
相关产品推荐
相关产品推荐

