我正在尝试确定如何有条件地设置架构配置属性。我已经尝试通过 dbt_project.yml 和 schema.yml 中的宏来执行此操作,但这两种方法都失败了:
00:23:19 Encountered an error:
Compilation Error
Could not render {{get_location_root('lndv')}}: 'get_location_root' is undefined
Run Code Online (Sandbox Code Playgroud)
我想要实现的结果是有条件地为 Spark 的各种模式设置location_root 。我想要每个环境的不同位置。我认为宏路径是最适合的,因为它遵循某种模式,但它显然不适用于dbt_project.yml或属性文件。我使用target.name来确定环境。它与在模型中成功渲染的其他宏位于同一目录中,因此路径设置正确。如果可以避免的话,我真的不想在每个模型中都放置此配置。
有人对我如何解决这个问题有任何想法吗?要么让宏在dbt_project.yml / schema.yml中工作,要么通过其他方法?
问候,
阿什利
dbt 只允许文件中存在一小部分 jinja .yml。特别是,您不能使用宏。但您可以使用简单的条件。文件中出现的 Jinja.yml必须被引用:
schema: "{{ 'prod_schema' if target.name == 'production' else 'dev_schema' }}"
Run Code Online (Sandbox Code Playgroud)
您的另一个选择是覆盖生成模式名称的内置宏。dbt 文档中有一篇关于这个主题的精彩文章。
来自文档:
如果您的 dbt 项目包含也名为generate_schema_name 的宏,则 dbt 将始终在您的 dbt 项目中使用该宏而不是默认宏。
因此,要更改 dbt 生成模式名称的方式,您应该将名为generate_schema_name 的宏添加到您的项目中,然后您可以在其中定义自己的逻辑。
该宏甚至还有一个与 dbt 一起提供的替代“非默认”版本,称为generate_schema_name_for_env,其逻辑为:
在产品中:
- 如果提供了自定义架构,则模型的架构名称应与自定义架构匹配,而不是连接到目标架构。
- 如果未提供自定义架构,则模型的架构名称应与目标架构匹配。
在其他环境中(例如 dev 或 qa):
- 在目标架构中构建所有模型,如忽略自定义架构配置。
要使用generate_schema_name_for_env,您需要在项目中创建一个包含以下内容的新宏:
-- put this in macros/generate_schema_name.sql
{% macro generate_schema_name(custom_schema_name, node) -%}
{{ generate_schema_name_for_env(custom_schema_name, node) }}
{%- endmacro %}
Run Code Online (Sandbox Code Playgroud)
location_clause编辑:在 Spark 中,您可以使用类似的技巧通过覆盖宏(它是 dbt-spark 适配器的一部分)来设置物化模型的“位置” 。您的宏应该模板化为一个字符串,其中包含单词“location”,后跟用单引号括起来的路径:
{% macro location_clause() %}
{%- set location_root = config.get('location_root', validator=validation.any[basestring]) -%}
{%- set identifier = model['alias'] -%}
{%- if location_root is not none and target.name == "production" %}
location '{{ location_root }}/prod/{{ identifier }}'
{%- elif location_root is not none %}
location '{{ location_root }}/dev/{{ identifier }}'
{%- endif %}
{%- endmacro -%}
Run Code Online (Sandbox Code Playgroud)