DBT:有条件地设置架构配置

Ash*_*tts 6 dbt

我正在尝试确定如何有条件地设置架构配置属性。我已经尝试通过 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中工作,要么通过其他方法?

问候,

阿什利

tco*_*eer 6

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)

  • `{% Macro Spark__location_clause() %} {%- set location_root = config.get('location_root', validator=validation.any[basestring]) -%} {%- setidentifier = model['alias'] -%} {%- if location_root is not none -%} {%- if target.name == 'prod' %} {{ log("Production", info=true) }} location '/mnt/prod/private/raw/ {{ location_root }}/{{ 标识符 }}' {%- else %} {{ log("非生产", info=true) }} 位置 '/mnt/dev/private/raw/{{target.schema }}_{{ location_root }}/{{ 标识符 }}' {%- endif %} {%- endif %} {%- endmacro -%}` (2认同)