You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在dbt中处理收敛模型?多租户多提供商架构适配咨询

注:本文重发自dbt-core仓库讨论,原讨论未获回应。

问题背景

  • 多租户架构:每个租户拥有独立的BigQuery数据集,用于各自的数据加载与转换。
  • 集成多竞争提供商:这些提供商覆盖同类领域实体,但表结构不同;每个租户仅使用其中一家的数据源。

示例DAG子集:

租户A(提供商P1):

P1.schedule --> std_schedule
P1.order --> std_order
P1.order_item --> std_order

租户B(提供商P2):

P2.t_schtemp --> std_schedule
P2.t_billinvoice --> std_order
P2.t_billitem --> std_order

核心问题:如何构建dbt项目以动态切换提供商?

拟议方案

针对支持同一标准模型(如std_schedule、std_order)多实现的初步思路:

  1. 每个租户单独执行一次dbt(因实现与架构不同)
  2. 为数据源(P1.*、P2.*)标记提供商标识符标签(如acme_provider、corp_provider)
  3. 为每个标准模型创建单个模型文件
  4. 将各提供商的自定义实现拆分到独立SQL文件,通过Jinja的include引入
  5. 基于传入的标签,在标准模型中实现不同实现的切换

方案可行性与疑问解答

你的拟议方案整体可行,是dbt处理多数据源适配标准模型的典型思路,针对你的疑问逐一解答:

1. dbt是否支持Jinja的include?这些引入文件是否需在dbt项目中标记为排除项?

dbt完全支持Jinja的include语法。建议将被引入的SQL片段放在专门的includes/目录,然后在dbt_project.yml中标记排除,避免dbt将其识别为独立模型:

models:
  your_project_name:
    +exclude:
      - includes/**/*

这样dbt只会在被include时解析这些片段,不会将其作为单独模型处理。

2. 传入标签时,dbt能否正确生成manifest?

只要标签通过dbt变量(如--vars参数)传递,dbt就能正确生成manifest。manifest是Jinja解析完成后生成的,变量值确定后,dbt会基于最终SQL构建依赖关系。注意:不同租户执行时要确保变量值正确传递,dbt Cloud中可通过独立作业隔离执行环境,避免缓存冲突。

3. 给定合适标签,dbt能否正确解析Jinja SQL?

可以。只要Jinja判断逻辑正确(比如{% if var('provider') == 'acme_provider' %}),dbt会在编译阶段正确解析并生成对应SQL。建议本地测试不同变量值下的编译结果,验证逻辑准确性。

4. 若集成dbt Cloud,该方案如何运作?

在dbt Cloud中落地该方案可按以下方式操作:

  • 为每个租户创建独立作业,通过环境变量或作业变量传递提供商标识符
  • 配置对应连接(或通过变量动态切换数据集的database/schema参数)访问租户的BigQuery数据集
  • 利用作业调度功能为不同租户设置独立执行计划
  • 通过环境隔离功能为不同租户配置专属环境,避免变量冲突

更优方案建议

除现有思路外,可考虑以下优化方向:

  1. 用宏替代include:将提供商适配逻辑封装为宏,通过变量调用,比include更灵活易维护。示例:
{% macro get_schedule_source(provider) %}
  {% if provider == 'acme_provider' %}
    select id, start_time from {{ source('p1', 'schedule') }}
  {% elif provider == 'corp_provider' %}
    select sch_id as id, sch_start as start_time from {{ source('p2', 't_schtemp') }}
  {% endif %}
{% endmacro %}

标准模型中调用:{{ get_schedule_source(var('provider')) }}

  1. 包管理隔离适配层:若提供商逻辑复杂,可将每个提供商的适配层封装为独立dbt包,主项目根据变量引入对应包,进一步隔离代码。

  2. 动态数据源配置:在dbt_project.yml中通过变量动态设置数据源schema,避免硬编码:

sources:
  your_project_name:
    p1:
      schema: "{{ var('tenant_schema_p1') }}"
      tables:
        - name: schedule
    p2:
      schema: "{{ var('tenant_schema_p2') }}"
      tables:
        - name: t_schtemp

内容的提问来源于stack exchange,提问作者Philippe Hebert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:40:26