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

为何DBT增量模型中宏先于pre_hook语句执行?

问题原因

dbt的执行分为编译阶段和运行阶段:

  • 编译阶段:模型中的宏(比如append_placekeys)会被直接展开为SQL语句,成为模型最终SQL的一部分。
  • 运行阶段:先执行pre_hook配置中的SQL,再执行模型的主SQL。

你当前的写法是把append_placekeys宏放在模型主SQL里,这会导致该宏对应的CALL语句在编译阶段就被写入主SQL。而pre_hook的建表语句要等到运行阶段、主SQL执行前才会执行,所以日志里显示宏先执行,临时表后创建。

解决方案

把append_placekeys宏的调用移到pre_hook列表中,放在创建临时表的语句之后,确保执行顺序为:建临时表 → 调用宏处理数据 → 模型主SQL读取处理后的临时表。

修改后的模型代码如下:

{{
    config(
           materialized='incremental',
           unique_key='DX_ID',
           pre_hook=[
                """
                    CREATE OR REPLACE TEMP TABLE DXH_STORE_PLCK_IN
                    AS
                    SELECT DISTINCT
                        s.dx_id AS msa_id,
                        s.nm AS store_name,
                        s.city AS city,
                        s.state AS state,
                        s.address AS street_addr,
                        s.zip5 AS zipcode,
                        s.country AS COUNTRY_CODE,
                        s.latitude AS LATITUDE,
                        s.longitude AS LONGITUDE,
                        COALESCE(p.last_updt_dt, TO_DATE('2023-01-01')) AS last_updt_dt
                    FROM {{ ref('dx_store_attr') }} s
                {%- if is_incremental() %}
                        FULL JOIN {{ this }} p USING (dx_id)
                    WHERE
                        (
                            p.placekey IS NULL
                        OR
                            DATEDIFF(day, p.last_updt_dt::DATE, CURRENT_TIMESTAMP()::DATE) > 90
                        )
                    ORDER BY last_updt_dt ASC, s.dx_id ASC
                    LIMIT 3000
                {%- else %}
                    LIMIT 50000
                {%- endif -%}
                ;
                """,
                # 将宏调用加入pre_hook,放在建表语句之后
                "{{ append_placekeys(tbl_in='DXH_STORE_PLCK_IN', tbl_out='DXH_STORE_PLCK_TEMP') }}"
            ],
        tags=["dx", "refresh:daily"]
    )
}}

SELECT
 t.msa_id AS dx_id,
 t.placekey AS placekey,
 t.error AS error,
 CURRENT_TIMESTAMP() AS last_updt_dt
FROM
 {{ database }}.{{ schema }}.DXH_STORE_PLCK_TEMP AS t

补充说明

  • pre_hook列表中的语句会按照从上到下的顺序依次执行,确保依赖关系正确。
  • 如果append_placekeys宏内部有动态生成逻辑,这种写法依然能正常工作,因为pre_hook中的jinja表达式会在编译阶段展开,运行阶段按顺序执行。

内容的提问来源于stack exchange,提问作者Raul E. Menendez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:11:32