使用文件夹结构的 DBT 自定义架构

Cat*_*zza 15 dbt

DBT 中有没有一种方法可以通过查看文件夹结构以派生方式为模型创建自定义架构?

\n

例如,假设这是我的结构:

\n
models\n\xe2\x94\x94-- product1\n    \xe2\x94\x94-- team1\n    |   \xe2\x94\x94-- model1.sql\n    \xe2\x94\x94-- team2\n        \xe2\x94\x94-- model2.sql\n
Run Code Online (Sandbox Code Playgroud)\n

在这种情况下, model1.sql 将在 schema 中创建product1_team1,而 model2.sql 将在 schema 中创建product1_team2。我想我可以在文件中“手动”指定这些内容dbt_project.yml,但我想知道是否有一种方法可以自动执行此操作 - 以便每个新模型或文件夹都会在正确的模式中自动创建。

\n

我正在查看自定义模式宏(https://docs.getdbt.com/docs/building-a-dbt-project/building-models/using-custom-schemas),但它似乎是简单的 jinja 或简单的 Python 内置 -插入。不确定我如何能够访问这些宏中的文件夹路径。

\n

另外,有没有办法用Python编写宏?因为知道文件路径和操作系统模块可能相对简单。

\n

gas*_*lho 9

您可以仅使用 Jinja 函数和 dbt 上下文变量来实现这一点。

正如您所注意到的,我们可以覆盖处理模式名称的 dbt 内置宏,幸运的是,有一种方法可以使用node宏参数中定义的变量来访问模型的路径。

fqn在这个例子中使用了该属性:

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

    {%- set default_schema = target.schema -%}

    {%- if custom_schema_name is none -%}

        {# Check if the model does not contain a subfolder (e.g, models created at the MODELS root folder) #}
        {% if node.fqn[1:-1]|length == 0 %}
            {{ default_schema }}    
        {% else %}
            {# Concat the subfolder(s) name #}
            {% set prefix = node.fqn[1:-1]|join('_') %}
            {{ prefix | trim }}
        {% endif %}

    {%- else -%}

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

    {%- endif -%}

{%- endmacro %}

Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

fqn属性将根据模型的位置返回一个列表,其中第一个位置将是 dbt 项目名称,最后一个位置将是模型的名称。因此,根据您的示例,我们将得到以下内容:

[<project_name>, 'product1', 'team1', 'model1']
Run Code Online (Sandbox Code Playgroud)

如果你这样做,dbt ls --m <model_name>你会发现输出正是fqn返回的

node.fqn[1:-1]是对列表进行切片的最短且最Pythonic 的方法。因此,该命令基本上删除了列表的第一个和最后一个位置(项目名称和模型名称),仅留下模型的剩余路径。

考虑到这一点,我们有一个条件来检查模型是否不包含子文件夹,因为如果是这种情况,我们将仅default_schema返回profiles.yml. 否则,我们继续使用joinJinja 函数将列表转换为字符串的逻辑。

如果您愿意,最好对变量进行日志记录,node以查看我们为其提供的所有可用选项。