如何在DBT模型间复用测试配置以减少重复代码?
解决DBT模型测试配置重复并支持差异化的方案
方案1:YAML锚点&引用(最简实现)
利用YAML原生的锚点特性定义通用测试模板,每个模型引用后仅修改差异化部分,无需额外宏开发。
示例schema.yml:
# 定义通用测试锚点,所有模型共享这部分配置 _common_column_tests: &common_column_tests - name: colB tests: - non_null - name: model1 columns: - name: colA tests: - accepted_values: values: ['a','b'] # 引用通用测试配置 <<: *common_column_tests - name: model2 columns: - name: colA tests: - accepted_values: values: ['a','b','c'] # 引用通用测试配置 <<: *common_column_tests
如果某模型需要额外测试,直接在引用后追加即可:
- name: model3 columns: - name: colA tests: - accepted_values: values: ['a'] <<: *common_column_tests # 追加该模型独有的测试 - name: colC tests: - unique
方案2:带参数的宏生成测试配置
你之前调用宏报错,是因为dbt解析schema.yml顶层结构时,直接渲染宏返回的列表会有解析限制,改用fromyaml函数解析宏输出的JSON字符串即可解决。
步骤1:定义宏(在macros/目录下创建common_tests.sql)
{% macro get_common_columns(cola_accepted_values) %} [ { "name": "colA", "tests": [ { "accepted_values": { "values": {{ cola_accepted_values | tojson }} } } ] }, { "name": "colB", "tests": ["non_null"] } ] {% endmacro %}
步骤2:在schema.yml中调用
- name: model1 columns: {{ fromyaml(get_common_columns(['a','b'])) }} - name: model2 columns: {{ fromyaml(get_common_columns(['a','b','c'])) }}
此方案通过参数传递差异化配置(如colA的可选值),同时复用90%的通用测试逻辑。
方案3:自定义通用测试宏
将重复的测试逻辑打包成自定义测试宏,进一步简化schema.yml的编写,后续修改规则仅需更新宏。
步骤1:定义自定义测试宏(macros/custom_tests.sql)
{% macro test_common_column_validation(model, column_name, accepted_values=None) %} {% if column_name == 'colA' and accepted_values %} -- 复用dbt内置的accepted_values测试 {{ test_accepted_values(model, column_name, values=accepted_values) }} {% elif column_name == 'colB' %} -- 复用dbt内置的non_null测试 {{ test_not_null(model, column_name) }} {% endif %} {% endmacro %}
步骤2:在schema.yml中调用
- name: model1 columns: - name: colA tests: - common_column_validation: accepted_values: ['a','b'] - name: colB tests: - common_column_validation - name: model2 columns: - name: colA tests: - common_column_validation: accepted_values: ['a','b','c'] - name: colB tests: - common_column_validation
内容的提问来源于stack exchange,提问作者Russell
相关产品推荐
相关产品推荐

