dbt:如何动态联合具有相同架构的多个模型

问题描述 投票:0回答:1

背景:

我每周都会使用相同的架构创建一个新表,并且其名称将始终具有相同的前缀。

表格示例:

模型 1 名称:avengers_au

名字 出生日期 国籍
xyz 2024-01-04 au
abc 2024-01-05 au

模型 2 名称:avengers_us

名字 出生日期 国籍
xyz 2024-01-04 我们
abc 2024-01-05 我们

...等等等等

当前解决方案

每次创建新表时,我都会手动执行 UNION ALL:

SELECT
   *
FROM
   avengers_au

UNION ALL

SELECT
   *
FROM
   avengers_us

... will add manually everytime there's a new table created

问题:

dbt 有什么方法可以自动化这个过程吗?

union dbt
1个回答
0
投票

我将为您提供我过去所做的事情的伪模板。您可以使用模型参考或基础源来执行此操作。您只需要根据您的情况稍微调整一下宏即可。另外,我的表列表是静态的。如果您的模型是动态的,您可以创建一个宏来从数据库平台的信息模式中检索列表,在模型上使用某种命名约定,您可以通过编程方式列出该列表,或者简单地在

dbt_project.yml
中更新列表(当列表发生变化时)(这就是我所做的)。

首先,我将表格/参考放入

dbt_project.yml

...
vars:
  avengers_sources:
    - model1
    - model2
    - model3
    ...

然后我有一个简单的宏,可以返回模型列表,类似于基本的

ref
宏的作用。你可以用“source”做同样的事情。

{% macro refs(var_name) %}
  {% set ref_name_list = var(var_name) %}
  {% set models = [] %}

  {% for model in ref_name_list %}
    {% do models.append(builtins.ref(model)) %}
  {% endfor %}

  {% do return(models) %}
{% endmacro %}

同样,如果需要,您可以将上述宏替换为查询信息模式的宏。

这是一个如何在模型中使用它进行联合的示例。同样在我的示例中,我允许包含某些模型中可能存在的可选列,但不是全部。

我的_model.sql:

WITH
{% set model_relations = refs('avengers_sources') %}

{% for model_relation in model_relations %}
  {{ model_relation.identifier}}_SOURCE AS (
    SELECT * FROM {{ model_relation }}
  ),
{% endfor %}

UNIONED AS (
  {% for model_relation in model_relations %}
    {%- set columns = dbt_utils.get_filtered_columns_in_relation(from=model_relation) -%}
    SELECT
        NAME,
        DATE_BIRTH,
        {% if 'NATIONALITY' in columns -%}
          NATIONALITY,
        {% else %}
          NULL::STRING NATIONALITY,
        {% endif %}
    FROM {{ model_relation.identifier}}_SOURCE
    {% if not loop.last %}
    UNION ALL
    {% endif %}
  {% endfor %}
)

SELECT * FROM UNIONED
© www.soinside.com 2019 - 2024. All rights reserved.