我试着用宏为我的快照创建一个临时表。但是,宏什么也不返回。这是我的宏代码:
{% macro notifications_clean() %}
{% if execute %}
{% set nc_sql %}
CREATE TEMPORARY TABLE temp_notifications AS
{% if var('full_load') == true %}
{{ log('Dropping existing snapshot for conforming_notifications.notifications and derived current table for notifications_current', info=True) }}
{% set dropsnapshot %}
DROP TABLE IF EXISTS conforming_notifications.notifications CASCADE;
{% endset %}
{% do run_query(dropsnapshot) %}
{{ log('Getting all data after last full load operation', info=True) }}
SELECT
*
FROM
raw_notifications.dbo_notifications
WHERE
etl_loaddate >= cast ((select max(etl_loaddate) from raw_notifications.dbo_notifications WHERE op = 'H') as date)
{% else %}
{{ log('Getting all cdc data after last snapshot operation', info=True) }}
SELECT
*
FROM
raw_notifications.dbo_notifications
WHERE
cdcoperationtimestamp >= (SELECT MAX(etl_loaddate) max_etl_loaddate FROM raw_notifications.dbo_notifications WHERE op = 'H')
{% endif %}
{% endset %}
-- {% do run_query(nc_sql) %}
{{ return(temp_notifications) }}
{% endif %}
{% endmacro %}
以下是我基于宏的快照:
{% snapshot notifications %}
{{
config(
target_database='dwh',
target_schema='conforming_notifications',
strategy='timestamp',
unique_key='id',
updated_at='cdcoperationtimestamp'
)
}}
SELECT
*
FROM
{{ notifications_clean() }}
{% endsnapshot %}
当收到的错误信息是时
00:45:38 Database Error in snapshot notifications (snapshots/conforming_notifications.sql)
00:45:38 syntax error at or near ")"
00:45:38 LINE 32: ) sbq
00:45:38 ^
00:45:38 compiled SQL at target/run/data_platform/snapshots/conforming_notifications.sql
欢迎来到dbt和SO.
这里发生了一些事情:
- Temp表在dbt中有点像反模式。临时表可能只是一个普通表,这意味着它可能是一个dbt模型,而不是宏。(dbt使用多个会话/到数据仓库的连接,由于会话结束时临时表将被丢弃,因此不能保证dbt可以查询它(
- DDL也是dbt中的一个反模式。dbt的全部意义在于它为您编写DDL。你只需要写一些看起来像select语句的东西,它就完成了剩下的部分
- 如果要在dbt宏等中使用DDL(比如用宏删除表(,则需要自己手动管理事务,并发出
COMMIT;
命令。否则,您的DDL可能会被回滚 - 您应该将jinja宏视为对机器上的文本文件进行操作,而不是对远程数据库进行操作。虽然可以使用
{{ run_query() }}
宏,但该宏通常只用于从数据库中获取一些值,以帮助模板化更大的查询。在大多数情况下,您并不真的希望使用宏向数据库发出指令(请参阅上面的#2(。因此,您并不真的希望宏返回查询,而是希望宏编写可以为该查询执行的SQL
有了这一点,我根本不会为您的用例使用宏。事实上,我认为你的桌子的普通快照会很好:
{% snapshot notifications %}
{{
config(
target_database='dwh',
target_schema='conforming_notifications',
strategy='timestamp',
unique_key='id',
updated_at='cdcoperationtimestamp'
)
}}
SELECT
*
FROM
raw_notifications.dbo_notifications
-- or ideally {{ source('raw_notifications', 'dbo_notifications') }}
{% endsnapshot %}
快照的部分工作是内省现有的快照,并且只追加新的/更新的记录。对于timestamp
策略,这应该是非常高效和高性能的(与您在宏中进行的过滤没有什么不同(——如果不是,那么向源表添加排序/分区/集群。与其他dbt管理的数据资产不同,快照实际上应该像源数据一样对待,而不是定期丢弃。