接上篇内容,如果是对DBT不太熟悉的朋友,建议从DBT介绍这篇文章开始阅读。
2.4、Snapshot
snapshots是什么
分析人员经常需要通过可变表中的以前的数据状态“回顾过去”。DBT提供了一种机制,即快照,它记录随时间推移对可变表的更改。
快照在可变源表上实现了缓慢变化维度。这些缓慢变化维度(scd)标识表中的一行如何随时间变 化。假设您有一个订单表,在处理订单时可以覆盖其中的状态字段。
同一个订单的状态从"pending"到"shipped"的变化:
在dbt中,快照是select语句,在 .sql 文件(通常在您的snapshots目录中)的snapshot块中定义。 您还需要配置快照以告诉 dbt 如何检测记录更改。
当您运行 dbt snapshot命令时:
- 在第一次运行时: dbt 将创建初始快照表 — 这将是select 语句的结果集,附加列包括 dbt_valid_from 和 dbt_valid_to。所有记录都将有一个 dbt_valid_to = null。
- 在后续运行中: dbt 将检查哪些记录已更改或是否已创建任何新记录:
- 已更改的任何现有记录的dbt_valid_to 列将会更新
- 更新的记录和任何新记录都将插入到快照表中。 这些记录现在将具有 dbt_valid_to = null
可以像引用模型一样在下游模型中引用快照——通过使用 ref 函数。
示例
要将快照添加到您的项目:
- 在您的snapshots目录中创建一个文件扩展名为 .sql 的文件,例如 snapshots/orders.sql
- 使用snapshot块来定义快照的开始和结束:
- 在snapshot块中编写一个 select 语句。此 select 语句定义了您想要随时间生成快照的结果。您可以 在此处使用sources和ref。
-
检查查询的结果集是否包含一个可靠的时间戳列,该列指示一条记录的最后更新时间。 对于我们的示例, updated_at 列可靠地指示记录更改,因此我们可以使用timestamp策略。 如果您的查询 结果集没有可靠的时间戳,则需要改用check策略
-
使用config块将配置添加到您的快照中。您还可以从 dbt_project.yml 文件配置快照
-
运行
dbt snapshot命令——对于我们的示例,将创建一个新表analytics.snapshots.orders_snapshot。更改 target_database 配置,target_schema 配置和快照名称(如 {% snapshot .. %} 中定义)将更改 dbt 命名此表的方式。 -
通过从dbt创建的表中检查结果。 第一次运行后,您应该会看到查询结果,以及快照元字段。
-
再次运行snapshot命令,并检查结果。 如果任何记录已更新,快照会反映这一点。
-
在下游模型中使用 ref 函数从快照中进行select。
- 安排snapshot命令定期运行——快照只有在你经常运行时才有用。
检测行变化 快照“策略”定义了dbt如何知道一行是否发生了更改。dbt中内置了两种策略——timestamp和check。
时间戳策略(推荐)
时间戳策略使用updated_at字段来确定一行是否发生了更改。如果为某一行配置的updated_at列比快照上次运行的时间更近,那么dbt将使旧记录无效,并记录新记录。如果时间戳没有改变,那么dbt将不采取任何操作。 时间戳策略需要进行如下配置:
Check策略
Check策略对于没有可靠updated_at列的表很有用。此策略通过比较列列表的当前值和历史值来起作用。 如果这些列中的任何一个发生了更改,则 dbt 将使旧记录无效并记录新记录。 如果列值相同,则 dbt 不会执行任何操作。
检查策略需要以下配置:
check_cols:检查更改的列列表,或检查所有列的all。
可以通过提供 check_cols = 'all' 配置check快照策略以跟踪对所有列的更改。最好显式枚举要检查的列。 考虑使用代理键将许多列压缩为一列。