You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

dbt+Databricks快照timestamp策略报错:时间戳未加引号引发语法错误

解决dbt Cloud + Databricks的timestamp策略快照语法错误问题

问题重现

使用dbt Cloud IDE搭配Databricks,采用timestamp策略创建快照,指定updated_at为created_at列,快照代码如下:

{% snapshot products_snapshot %}

    {{ config(
            target_schema='bronze',
            strategy='timestamp',
            unique_key='id',
            updated_at='created_at'
        )
    }}

    select * from {{ source('landing', 'products') }}

{% endsnapshot %}

执行dbt snapshot时触发[PARSE_SYNTAX_ERROR],原因是生成的SQL中时间戳字面量未被引号包裹,导致Databricks无法识别格式。

解决方案

1. 确保时间戳列类型正确

如果源表的created_at是字符串类型,Databricks无法直接识别为时间格式进行比较,需显式转换为timestamp类型:

{% snapshot products_snapshot %}

    {{ config(
            target_schema='bronze',
            strategy='timestamp',
            unique_key='id',
            updated_at='created_at'
        )
    }}

    select 
        id,
        name, -- 替换为你的实际业务字段
        price,
        cast(created_at as timestamp) as created_at -- 显式转换为timestamp类型
    from {{ source('landing', 'products') }}

{% endsnapshot %}

若字符串格式非Databricks默认格式(如yyyy-MM-dd HH:mm:ss),需指定格式转换:

cast(created_at as timestamp format 'yyyy/MM/dd HH:mm:ss') as created_at

2. 升级dbt-databricks适配器

旧版本的dbt-databricks适配器可能存在timestamp策略下生成SQL的bug,导致时间戳字面量未正确添加引号。在dbt Cloud的项目设置中,将dbt-databricks依赖升级至最新稳定版,重新执行快照命令。

3. 自定义快照宏修复SQL生成逻辑

如果上述方法无效,可自定义宏覆盖默认的timestamp策略SQL生成逻辑,确保时间戳值被正确包裹:
在项目的macros/snapshots目录下新建custom_timestamp_snapshot.sql文件,内容如下:

{% macro get_timestamp_snapshot_sql(target_relation, source_relation, snapshot_args) %}
    {% set unique_key = snapshot_args['unique_key'] %}
    {% set updated_at = snapshot_args['updated_at'] %}
    {% set snapshot_id = snapshot_args['snapshot_id'] %}

    {% set select_new_rows = %}
        select
            s.*,
            current_timestamp() as dbt_valid_from,
            cast(null as timestamp) as dbt_valid_to,
            '{{ snapshot_id }}' as dbt_snapshot_id
        from {{ source_relation }} s
        left join {{ target_relation }} t
            on s.{{ unique_key }} = t.{{ unique_key }}
        where t.{{ unique_key }} is null
           or s.{{ updated_at }} > coalesce(t.{{ updated_at }}, '1970-01-01 00:00:00'::timestamp)
    {% endset %}

    {% set update_old_rows = %}
        update {{ target_relation }} t
        set dbt_valid_to = current_timestamp(),
            dbt_snapshot_id = '{{ snapshot_id }}'
        from {{ source_relation }} s
        where t.{{ unique_key }} = s.{{ unique_key }}
          and s.{{ updated_at }} > t.{{ updated_at }}
          and t.dbt_valid_to is null
    {% endset %}

    {% do return([select_new_rows, update_old_rows]) %}
{% endmacro %}

保存后重新执行dbt snapshot,宏会确保时间戳字面量被引号包裹并正确转换类型。

内容的提问来源于stack exchange,提问作者Datapher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:35:07