6

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

4

3 回答 3

11

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

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

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

选项 1:使用具体化将您的模型具体化为 CTE ephemeral文档

优点:

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

缺点:

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

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

我通常建议不要这样做——你不能测试或记录你的模型,它们不会出现在谱系图中(正如你所指出的)。

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

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

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

优点:

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

缺点:

  • 确保您在该模式之上没有任何依赖视图!当您运行drop cascade命令时,它们可能会被丢弃!这会在您的项目中引入脆弱性!
于 2020-07-23T13:48:11.180 回答
0

两种解决方案:

  1. 创建源 (SRC) 模型,以便您可以将源与暂存模型分开。
  2. 直接使用暂存模型构建源代码。

这些都应该显示在血统图上。

于 2020-07-22T10:17:02.527 回答
0

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

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