dbt 增量物化策略简单说明

dbt 物化模型是支持增量处理的,实际场景中基于增量的数据处理还是比较重要的,dbt 对于增量的处理会和一些因素有关系,比如数据大小,
可靠的unique_key 以及特定数据平台的支持incremental_strategy 策略可以对于特定adapter 支持配置

目前支持的增量策略

当然与实际上的adapter 是有关系的,但是了解有助于学习数据增量的一些处理,目前支持的策略append,merge,delete+insert,insert_overwrite
从dbt v1.6 开始,pg以及redshift 支持了merge 策略

策略配置说明

可以通过项目级别以及模型配置

  • merge 策略配置
    一般我们需要配置的是unique_key, dbt 会使用新指对于整个匹配到的行进行重写,一些数据库的adapter 支持配置merge_update_columns ,同时也可以进行merge_exclude_columns
    的配置
  • 其他测试配置
    官方文档没有完整的介绍,但是可以结合源码学习,对于新版本是dbt-adapter 中 dbt/include/global_project/macros/materializations/models/incremental/strategies.sql 文件

策略对应的macro

了解策略对应的macro 可以方便学习以及进行改造

  • append
    get_incremental_append_sql
  • delete+insert
    get_incremental_delete_insert_sql
  • merge
    get_incremental_merge_sql
  • insert_overwrite
    get_incremental_insert_overwrite_sql
    append 参考处理
{% macro get_incremental_append_sql(arg_dict) %}
 
  {% do return(some_custom_macro_with_sql(arg_dict["target_relation"], arg_dict["temp_relation"], arg_dict["unique_key"], arg_dict["dest_columns"], arg_dict["incremental_predicates"])) %}
 
{% endmacro %}
 
{% macro some_custom_macro_with_sql(target_relation, temp_relation, unique_key, dest_columns, incremental_predicates) %}
    # get_quoted_csv 是dbt 包含的一个增量处理帮助maco
    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute="name")) -%}
 
    insert into {{ target_relation }} ({{ dest_cols_csv }})
    (
        select {{ dest_cols_csv }}
        from {{ temp_relation }}
    )
 
{% endmacro %}

incremental_predicates

此配置属于一个过滤,对于数据量比较大,我们希望只处理特定范围的数据比较方便,此参数属于一个数组,可以配置比较多的过滤
参考配置

{{
  config(
    materialized = 'incremental',
    unique_key = 'id',
    cluster_by = ['session_start'],  
    incremental_strategy = 'merge',
    incremental_predicates = [
      "DBT_INTERNAL_DEST.session_start > dateadd(day, -7, current_date)"
    ]
  )
}}

内部参考处理(DBT_INTERNAL_SOURCE以及DBT_INTERNAL_DEST 属于内部的一个实践命名)

merge into <existing_table> DBT_INTERNAL_DEST
    from <temp_table_with_new_records> DBT_INTERNAL_SOURCE
    on
        -- unique key
        DBT_INTERNAL_DEST.id = DBT_INTERNAL_SOURCE.id
        and
        -- custom predicate: limits data scan in the "old" data / existing table
        DBT_INTERNAL_DEST.session_start > dateadd(day, -7, current_date)
    when matched then update ...
    when not matched then insert ...
 
with large_source_table as (
 
    select * from {{ ref('large_source_table') }}
    {% if is_incremental() %}
        where session_start >= dateadd(day, -3, current_date)
    {% endif %}
 
),
...

自定义策略

核心是对于物化的自定义,格式为 get_incremental_STRATEGY_sql STRATEGY 是自定义的策略名称,比如一个insert_only 的
注意对于自定义的策略dbt 是不关系内部处理的,核心是macro 的调用

{% macro get_incremental_insert_only_sql(arg_dict) %}
 
  {% do return(some_custom_macro_with_sql(arg_dict["target_relation"], arg_dict["temp_relation"], arg_dict["unique_key"], arg_dict["dest_columns"], arg_dict["incremental_predicates"])) %}
 
{% endmacro %}
 
 
{% macro some_custom_macro_with_sql(target_relation, temp_relation, unique_key, dest_columns, incremental_predicates) %}
 
    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute="name")) -%}
 
    insert into {{ target_relation }} ({{ dest_cols_csv }})
    (
        select {{ dest_cols_csv }}
        from {{ temp_relation }}
    )
 
{% endmacro %}

使用

{{ config(
    materialized="incremental",
    incremental_strategy="insert_only",
    ...
) }}
...

说明

实际业务中进行数据的增量处理是很有价值的,可以加速数据处理,同时有助于优化速度,但是只有合理的使用了策略才能包装数据的准确以及高效,同时官方对于不同
数据库的实现基本都已经分离了,可以参考源码学习

参考资料

https://docs.getdbt.com/docs/build/incremental-strategy#strategy-specific-configs
https://docs.getdbt.com/docs/build/incremental-strategy#custom-strategies
https://docs.getdbt.com/guides/create-new-materializations?step=3
https://discourse.getdbt.com/t/incremental-best-practices/11495
https://github.com/dbt-labs/dbt-redshift/tree/main/dbt/include/redshift/macros/materializations
https://github.com/dbt-labs/dbt-adapters/blob/main/dbt/include/global_project/macros/materializations/models/incremental/strategies.sql

posted on 2024-04-25 07:07  荣锋亮  阅读(84)  评论(0编辑  收藏  举报

导航