dbt Cloud对接PostgreSQL多schema场景下ref指向默认schema报错如何解决
这不是dbt Cloud对接PostgreSQL的功能限制,属于对dbt模型和引用逻辑的认知偏差+配置缺失导致的问题,核心逻辑说明:
{{ref('模型名')}}引用的是dbt自身构建物化后的模型产物,不是你数据库里的原始业务表- 模型内部写的读取源表的路径,不会决定这个模型本身被dbt构建后存放在哪个schema
- dbt默认会把所有未单独指定schema的模型,全部放到项目配置的默认schema(也就是你现在看到的
jaffle_shop)下,这个逻辑在所有支持的数仓(包括Snowflake、BigQuery等付费数仓)上完全一致。
根据你的实际需求选对应方案即可:
方案1:常规项目推荐做法(原始表和dbt模型分离存放)
绝大多数生产场景下,不会把dbt构建的模型和原始业务表混放在同一个schema下,一般是原始表按业务域存在不同schema,dbt产出的所有模型统一放在dbt专用的schema里。
你现在硬编码写from dbt.stripe.payment的写法不具备可移植性,应该用dbt原生的source功能声明源表:
- 在models目录下新建
sources.yml,声明跨schema的源表信息:
version: 2 sources: - name: stripe schema: stripe tables: - name: payment
- 修改
stg_payments.sql模型,把硬编码的源表路径替换为source引用:
with payment as ( select orderid as order_id, amount from {{ source('stripe', 'payment') }} ) select * from payment
配置完成后重新运行dbt run,stg_payments模型会正常构建在默认的jaffle_shop schema下,{{ref('stg_payments')}}会自动编译到正确的模型路径,读取源表时也会自动定位到stripe schema下的原始payment表,不需要硬编码全路径,后续切换部署环境也不需要改模型代码。
方案2:需要把stg_payments模型构建到stripe schema下
如果你确实需要把这个dbt模型存到stripe schema而非默认schema,给模型添加schema配置即可,有两种配置粒度可选:
- 单模型配置:在
stg_payments.sql文件头部添加config块
{{ config( schema = 'stripe' ) }} with payment as ( select orderid as order_id, amount from {{ source('stripe', 'payment') }} ) select * from payment
- 目录级批量配置:如果某一个目录下的所有模型都需要放到stripe schema,可以在项目根目录的
dbt_project.yml里给对应路径添加统一配置:
models: 你的dbt项目名: staging: stripe: +schema: stripe
注意:dbt默认的schema生成规则会给自定义schema添加目标schema前缀,比如你配置的目标schema是
jaffle_shop,给模型配了schema='stripe',默认会把模型构建到jaffle_shop_stripeschema下。如果需要直接使用stripe作为schema名、不加前缀,需要在项目macros目录下覆写generate_schema_name宏,自定义schema命名逻辑即可。
内容的提问来源于stack exchange,提问作者Vaslo

