DBT增量模型:如何在新增或更新行时记录更新时间戳?
使用dbt实现带条件更新时间戳的增量模型
完全可以实现,核心是通过dbt增量模型+自定义MERGE逻辑,仅在数据行新增或指定字段发生变更时更新updated_at时间戳,未变更时保持原时间戳不变。
实现步骤及代码示例
假设你的模型有唯一键id,需要监控col1、col2字段的变化,以下是具体实现:
- 模型配置与基础查询
{{ config( materialized='incremental', incremental_strategy='merge', unique_key='id' -- 替换为你的实际唯一键字段 ) }} with source_data as ( select id, col1, col2, current_timestamp() as created_at, -- 新增行的创建时间 current_timestamp() as updated_at -- 初始更新时间 from {{ source('your_source_schema', 'source_table') }} -- 替换为你的源数据 ) select * from source_data
- 自定义MERGE更新逻辑(关键)
在增量模式下,通过post-hook覆盖默认的MERGE行为,添加字段变更判断:
{% if is_incremental() %} {{ config( post_hook=[ """ merge into {{ this }} as target using source_data as source on target.id = source.id -- 仅当监控字段发生变化时,才更新数据和时间戳 when matched and ( coalesce(target.col1, '') != coalesce(source.col1, '') or coalesce(target.col2, 0) != coalesce(source.col2, 0) -- 继续添加需要监控变化的字段,注意处理null值 ) then update set target.col1 = source.col1, target.col2 = source.col2, target.updated_at = current_timestamp() -- 新增行直接插入 when not matched then insert (id, col1, col2, created_at, updated_at) values (source.id, source.col1, source.col2, source.created_at, source.updated_at) """ ] ) }} {% endif %}
关键注意事项
- null值处理:使用
coalesce将null转换为统一默认值(比如空字符串、0),避免因null对比导致的误判。 - 监控字段维护:所有需要触发时间戳更新的字段都要加入
when matched的条件中,不需要监控的字段可忽略。 - 唯一键准确性:确保
unique_key能精准匹配源数据与目标表的同一行,避免匹配错误。
内容的提问来源于stack exchange,提问作者kathryn
相关产品推荐
相关产品推荐

