如何让dbt宏返回一个表

  • 本文关键字:一个 返回 dbt dbt
  • 更新时间 :
  • 英文 :


我试着用宏为我的快照创建一个临时表。但是,宏什么也不返回。这是我的宏代码:

{% 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.

这里发生了一些事情:

  1. Temp表在dbt中有点像反模式。临时表可能只是一个普通表,这意味着它可能是一个dbt模型,而不是宏。(dbt使用多个会话/到数据仓库的连接,由于会话结束时临时表将被丢弃,因此不能保证dbt可以查询它(
  2. DDL也是dbt中的一个反模式。dbt的全部意义在于它为您编写DDL。你只需要写一些看起来像select语句的东西,它就完成了剩下的部分
  3. 如果在dbt宏等中使用DDL(比如用宏删除表(,则需要自己手动管理事务,并发出COMMIT;命令。否则,您的DDL可能会被回滚
  4. 您应该将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管理的数据资产不同,快照实际上应该像源数据一样对待,而不是定期丢弃。

最新更新