自定义schema
什么是自定义schema?¶
默认情况下,所有dbt模型都是在目标中指定的schema中构建的。在有很多模型的dbt项目中,在目标schema之外的schema中构建一些模型可能会很有用——这可以帮助模型更有逻辑地分组在一起。
例如,您可能希望:
* 根据使用该模型的业务部门对模型进行分组,创建诸如core, marketing, finance 和 support等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文件中指定它,将其应用于模型的子目录
# `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匹配.
-
在其它环境(比如
dev或qa): - 在目标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中管理环境