【发布时间】:2021-06-07 10:46:44
【问题描述】:
如何在 DBT 中使用 Update 语句? 我们使用 DBT 在 Snowflake 中创建了表,但无法使用 Update 查询来更新同一个表。
有没有其他方法可以实现这一点,就像其他 ELT/ETL 工具一样?
【问题讨论】:
-
dbt 旨在创建幂等转换。将记录加载到上游表中,并仅选择下游模型中需要的记录。
标签: dbt
如何在 DBT 中使用 Update 语句? 我们使用 DBT 在 Snowflake 中创建了表,但无法使用 Update 查询来更新同一个表。
有没有其他方法可以实现这一点,就像其他 ELT/ETL 工具一样?
【问题讨论】:
标签: dbt
DBT 不允许像我们在 SQL 中那样轻松地使用 DDL 和 DML 操作。要更新从 DBT 内的模型创建的雪花数据库上的表,您可以使用模型顶部的 Post_Hook 配置来调用 post_hook 内的宏。
例如。
宏:
{% 宏 UpdatebaseTable(DatasetKey) %}
更新表 A
放
COL = ClnCOl
来自表A
左连接表B
在表 A.COl1= 表 B.COl1
其中 TableA.DatasetKey = {{DatasetKey}};
{% endmacro %}
模型:在模型内部调用宏作为 post_hook
{{ 配置 ( 物化='表', post_hook = UpdatebaseTable("'dataset_XXXX'"), ) }}
【讨论】:
虽然与dbt的设计相违背,不推荐,但可以使用pre_hook或post_hook进行merge/update/delete等SQL语句。只需添加 pre/post_hook 并使用 {{ this }} 变量。
示例(您可以将其放入您的 <model>.sql 文件中):
{{ config(
post_hook=“UPDATE {{ this }} SET column_name=‘value’”
) }}
请记住,当 dbt 运行时,它已经将模型主体中的 SELECT 编译为:
create or replace table 声明(如果实现不是增量的)这意味着理想情况下,您应该编写查询主体以包含您在 UPDATE 中的任何逻辑。如果您想保持转换分开,您还可以创建一个子模型并将 UPDATE 逻辑放在其 SELECT 中。这将确保您的表和转换是幂等的。
【讨论】:
显然,除了 DBT 之外,还有许多 ELT/ETL 工具可供您使用,所以我们不要走这条路。像StackShare 这样的网站将是您对工具/堆栈做出决策的更好场所。
但是,可以让 DBT 运行任何普通的 SQL 语句(DDL、DML 等)。 DBT 使用他们所谓的“materializations”来执行模型。关键是create a custom materialization满足您的需求。
如果您不想经历创建自定义实现的麻烦,那么您很幸运!我创建了一个DBT package with such a materialization。具体化称为plain,您可以在repo/readme 中找到所有说明。
【讨论】:
我也遇到了这个问题,根据这个 dic https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models
{{
config(
materialized='incremental',
unique_key='payment_id',
incremental_strategy='insert_overwrite'
)
}}
select
...
from orders o
left join member m on o.member_id = m.member_id
left join payment p on o.order_id = p.order_id
{% if is_incremental() %}
where 1=1
and p.gmt_updated >= (select max(payment_gmt_updated) from {{ this }})
{% endif %}
当源表支付更新时 ->“dbt 运行” -> 我的接收器表也得到更新(具有相同的 payment_id)
【讨论】: