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

DBT custom schema using folder structure

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

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

models
└-- product1
    └-- team1
    |   └-- model1.sql
    └-- team2
        └-- model2.sql

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

我正在查看自定义模式 macros (https://docs.getdbt.com/docs/building-a-dbt-project/building-models/using-custom-schemas),但它似乎是普通的 jinja 或简单的 Python 内置函数。不确定如何访问 those macros.

中的文件夹路径

另外,有没有办法在Python中写一个宏?因为知道文件路径和 os 模块可能相对简单。

您可以仅使用 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 %}

fqn 属性 将 return 一个基于模型位置的列表,其中第一个位置是 dbt 项目名称,最后一个位置是模型名称.因此,根据您的示例,我们将有以下内容:

[<project_name>, 'product1', 'team1', 'model1']

If you do a dbt ls --m <model_name> you'll notice that the output is exactly what fqn returns

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

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

In case you want, it would be good to do a log of the node variable to see all the available options we have for it.