Skip to content

自定义schema

什么是自定义schema?

默认情况下,所有dbt模型都是在目标中指定的schema中构建的。在有很多模型的dbt项目中,在目标schema之外的schema中构建一些模型可能会很有用——这可以帮助模型更有逻辑地分组在一起。

例如,您可能希望: * 根据使用该模型的业务部门对模型进行分组,创建诸如core, marketing, financesupport等schema;或, * 在临时schema中隐藏中间模型,在分析 schema中只显示最终用户应该查询的模型。

您可以在dbt中使用 自定义schemas 在目标schema之外的schema中构建模型。需要注意的是,默认情况下,dbt将通过 将自定义schema连接到目标schema 来生成模型的模式名称,如:<target_schema>_<custom_schema>;

目标schema 自定义schema 结果schema
<target_schema> None <target_schema>
analytics None analytics
dbt_alice None dbt_alice
<target_schema> <custom_schema> <target_schema>_<custom_schema>
analytics marketing analytics_marketing
dbt_alice marketing dbt_alice_marketing

如何使用自定义schemas?

使用schema配置键可以为模型指定自定义架构。与任何配置一样,您可以:

  • 通过在模型中使用配置块将此配置应用于特定模型,或者
  • 通过在dbt_project.yml文件中指定它,将其应用于模型的子目录

{{ config(schema='marketing') }}

select ...

# `models/marketing/`里的模型将呈现在"*_marketing" schema中
models:
  my_project:
    marketing:
      +schema: marketing

了解自定义schemas

为什么dbt将自定义schema连接到目标schema?

当首次使用自定义schema时,通常会假设模型将建立在与schema配置完全匹配的schema中,例如,具有schema: marketing配置的模型将建在marketingschema中。然而,dbt默认情况下会在类似<target_schema>_marketing的schema中创建它——这是有充分理由的!

在dbt的典型设置中,每个dbt用户都将使用一个单独的目标schema(请参阅管理环境)。如果dbt在一个与模型的自定义schema完全匹配的schema中创建模型,那么每个dbt用户都会在同一schema下创建模型。

此外,构建开发模型的schema将与构建生产模型的schema相同!相反,将自定义schema连接到目标schema有助于创建不同的schema名称,从而减少命名冲突。

如果您喜欢使用不同的逻辑来生成schema名称,那么可以更改dbt生成schema名称的方式(见下文)。

dbt是如何生成模型的schema名称?

在后台,dbt使用一个名为generate_schema_name的宏来确定应该在其中构建模型的schema的名称。表示当前逻辑的宏代码如下:

{% macro generate_schema_name(custom_schema_name, node) -%}

    {%- set default_schema = target.schema -%}
    {%- if custom_schema_name is none -%}

        {{ default_schema }}

    {%- else -%}

        {{ default_schema }}_{{ custom_schema_name | trim }}

    {%- endif -%}

{%- endmacro %}

高级自定义schema配置

更改dbt生成schema名称的方式

如果您的dbt项目包含一个名为generate_schema_name的宏,则dbt将始终使用dbt项目中的宏,而不是默认宏。

因此,要改变dbt生成schema名称的方式,您应该在项目中添加一个名为generate_schema_name的宏,然后在其中定义自己的逻辑。

注意:dbt会忽略任何自定义的generate_schema_name宏,这些宏是安装在项目中的包的一部分。

生成schema名称的另一种模式

生成schema名称的一种常用模式是根据dbt的环境更改行为,以便:

  • 在产品环境下:
  • 如果提供了自定义schema,则模型的schema名称应该与自定义schema匹配,而不是连接到目标schema。
  • 如果没有提供自定义schema,则模型的schema名称应该与目标schema匹配.

  • 在其它环境(比如devqa):

  • 在目标schema中构建 all 模型,如中所示,忽略自定义schema配置.

dbt附带了一个包含此逻辑的全局宏generate_schema_name_for_env

如果您想使用这种模式,那么您的项目中需要一个指向这种逻辑的generate_schema_name宏。您可以通过在macross目录中创建一个文件(我们通常称之为get_custom_schema.sql),然后粘贴以下内容来完成此操作:

-- put this in macros/get_custom_schema.sql

{% macro generate_schema_name(custom_schema_name, node) -%}
    {{ generate_schema_name_for_env(custom_schema_name, node) }}
{%- endmacro %}

注意: 使用此宏时,如果希望应用自定义schema,则需要将作业中的目标名称专门设置为prod

generate_schema_name参数

参数 说明 示例
custom_schema_name 指定节点中schema的配置值,如果未提供值,则为none marketing
node dbt当前正在处理的“节点” {"name": "my_model", "resource_type": "model",...}

generate_schema_name中提供的Jinja上下文

如果您选择编写自定义逻辑来生成schema名称,那么值得注意的是,在定义此逻辑时,并非所有变量和方法都可用。换句话说:generate_schema_name宏是使用有限的Jinja上下文编译的。

generate_schema_name宏中提供的以下上下文方法:

Jinja context Type Available
target Variable
env_var Variable
var Variable Limited, see below
exceptions Macro
log Macro
Other macros in your project Macro
Other macros in your packages Macro

generate_schema_name哪些变量可用?

dbt v0.17.0中的变量语义发生了变化。请参阅迁移指南

全局范围的变量和在命令行上定义的变量--vars 可在generate_schema_name上下文中访问

管理环境

在上面显示的generate_schema_name宏示例中,target.name上下文变量用于更改dbt为模型生成的模式名称。如果项目中的“generate_schema_name”宏使用“target.name”上下文变量,则还必须确保适当配置不同的dbt环境。虽然您可以使用任何想要的命名方案,但我们通常建议您: - dev: 您的本地开发环境;配置在您计算机上的profiles.yml文件中. * ci: 在github、GitLab等运行的Pull Requests持续集成 环境. - prod: dbt项目的生产部署,例如dbt Cloud,Airflow或相似.

如果您的schema名称生成错误,请在相关环境中仔细检查您的目标名称。

有关更多信息,请参阅在dbt Core中管理环境