DBT 是否支持创建临时表,如 create table #temp1 as select * from tab1 或者它仅适用于 CTE 方式

Nik*_*s A 4 dbt

我找到了一种处理 DBT 中临时表的方法,将所有这些写在预钩中并在预钩外部调用最终临时表,经过测试并且工作正常,能够减少代码运行时间超过 20 分钟到 1 分钟。但是我看到一个问题,我们在 DBT 文档中看不到谱系图。除了 pre-hook 和 Docs 中的 lineage 之外,还有什么方法可以处理临时表吗?

Cla*_*oll 7

您认为 dbt 不支持临时表是正确的。那是因为临时表只在单个​​会话中持续存在,而 dbt 每个线程打开一个连接/会话。因此,在一个线程上创建的任何临时表对于在不同线程上运行的模型都是不可见的。

听起来 CTE 对您来说是一种性能拖累——出于兴趣,您使用的是哪个仓库?

您已经确定了两种解决方法,还有另一种值得讨论:

选项 1:使用具体ephemeral化 ( docs )将您的模型具体化为 CTE

优点:

  • 模型显示在谱系图中
  • 您可以通过ref-ing在多个下游模型中重用这些转换
  • 您可以测试和记录这些模型

缺点:

  • 在某些时候,堆叠 CTE 过多会导致性能下降(尤其是在较旧版本的 postgres 上,其中 CTE 是优化栅栏)
  • 编译后的 SQL 可能更难调试

选项 2:使用预挂钩创建临时表

我通常不建议这样做 - 您无法测试或记录您的模型,并且它们不会出现在谱系图中(正如您所指出的)。

选项 3:将这些模型具体化为单独模式中的表,并在运行结束时删除该模式

我认为迈克尔的建议很好!我会稍微调整一下:

  1. 使用架构配置在单独的架构中实现模型
{{ config(
  materialized='table',
  schema='my_temporary_schema'
) }}
Run Code Online (Sandbox Code Playgroud)
  1. 然后,在运行结束时,使用on-run-end钩子 ( docs ) 删除该架构 - 在您的dbt_project.yml
on-run-end: "drop schema my_temporary_schema cascade"
Run Code Online (Sandbox Code Playgroud)

优点:

  • 选项 1 的所有好处
  • 听起来它可能比使用 CTE 性能更好

缺点:

  • 确保在该架构之上没有任何依赖视图!当您运行drop cascade命令时,它们可能会被丢弃!这给您的项目带来了脆弱性!


小智 0

我认为有两种方法可以在保留文档中的沿袭的同时获得相同的结果:

  1. 将每个临时表编写为单独的模型,其中逻辑发生在 pre_hook 中(就像您建议的那样),并且模型只是带有逻辑的视图select * from YOUR_TEMP_TABLE_NAME
  2. on-run-end不要使用临时表,而是将每个表创建为常规模型,然后将它们放入使用它们的“最终”模型的 post_hook 中或放入dbt_project.yml.