引
在上一篇文章中,我们花了专门的篇幅介绍了 dbt 更多实用的命令,那么我们继续按照之前的约定来聊 dbt 中你可能会遇到的疑惑以及有用的概念,如果你是 dbt 初学者,我相信如下知识点一定会对你有极大的帮助:
- 了解
dbt_project
配置文件,以及不同字符的作用 - 了解 dbt 工程化,为 dev 以及 prod 模式配置不同的目标数据集
- 了解
model
禁用与动态禁用 - 引用表的三种方式,dbt 如何维护
model
的依赖关系? macro
使用说明- 如何创建和使用增量表
那么让我们开始本篇内容的学习。
一、了解 dbt_project
字段含义
dbt 项目中有两个非常重要的配置文件:
profiles.yml
:用于定义项目的 dbt 适配器配置,如果连接的数据库或者数据平台不同,字段会有所不同,此配置可区分开发和生产环境(一个环境一个配置)
dbt_project.yml
:dbt 项目自身的配置,例如定义项目模型文件的存放地址,不同模型的创建规则等等。
以下是一个非常常见的 dbt_project
配置,事实上你需要特别注意的字段并不多,因此我会解释你在工作中需要留意的字段,如果某个字段我没过多解释,那说明你只需要跟着这么配置就好了:
name: 'dbt_models'
version: '1.0.0'
config-version: 2
profile: 'bigquery_profile'
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]
docs-paths: ["docs"]
target-path: "target" # directory which will store compiled SQL files
clean-targets: # directories to be removed by `dbt clean`
- "target"
- "dbt_packages"
models:
dbt_models:
+materialized: table
details:
+materialized: view
+schema: "{
{ 'mc_data_statistics' if target.name == 'dev' else 'details' }}"
summary:
+materialized: table
+schema: "{
{ 'mc_data_statistics' if target.name == 'dev' else 'summary' }}"
dau:
+enabled: true
mau:
+enabled: "{
{ var('run_mau', false) }}"
**name:**项目名称,在上篇 dbt 命令篇章我们也提到了这个字段,当你需要指定运行某个项目的所有模型,或者为某个项目的一些目录配置不同权限时都会用到这个字段;命令上篇文章有解释,而关于权限配置我们在下文会详细介绍。
**profile:**dbt 项目需要配合 dbt 适配器连接数据库,前面我们已经提过了 profiles.yml
用于定义适配器配置,而这里的 profiles 提供 profiles.yml
内的名称即可(配置中的第一行代码),比如我当前的 profiles.yml
配置如下。
bigquery_profile:
target: prod
outputs:
dev:
type: bigquery
method: service-account
project: notta-data-analytics
dataset: dev
threads: 1
timeout_seconds: 300
location: US
priority: interactive
retries: 1
keyfile: xxx.json
prod:
type: bigquery
method: service-account
project: notta-data-analytics
dataset: dbt_models
threads: 1
timeout_seconds: 30000
location: US
priority: interactive
retries: 1
keyfile: xxx.json
**model-paths:**告诉 dbt 项目你的模型在哪个目录,其实我之前也好奇,为什么我运行 dbt run
dbt 就知道去哪找到我定义的模型并运行它们, 那么这里的配置其实就是在告诉 dbt 项目中模型在哪个目录下,一般情况下直接用模版仓库默认的目录名与配置名并它们能一一匹配对应即可。
model-paths 下面的几个字段同理,都是在告诉 dbt 不同功能文件所在的目录地址,如果某个目录你不要,那么对应的配置你可以删除。
比如上图中我们并未使用 docs
,理论上docs-paths: ["docs"]
这行配置可以删掉。
接下来让我们将目光聚焦到 models
开头的这一串配置代码:
models:
dbt_models:
+materialized: table
details:
+materialized: view
+schema: "{
{ 'mc_data_statistics' if target.name == 'dev' else 'details' }}"
summary:
+materialized: table
+schema: "{
{ 'mc_data_statistics' if target.name == 'dev' else 'summary' }}"
dau:
+enabled: true
mau:
+enabled: "{
{ var('run_mau', false) }}"
通过这段配置,我将解释 dbt 项目中权限覆盖的优先级以及文章开头提到的如何通过配置区分开发与生产环境,不同环境将 model
写入到不同的数据集中,让我们接着聊。
二、dbt 项目中的配置优先级
在 dbt 项目中像 models
、seeds
目录都代表了不同重要意义的文件,事实上我们会遇到对不同项目,或者项目下不同目录的 model
运行不同规则的情况;
举个例子,由于 dbt 项目能通过 package 直接引用三方 dbt 包,而这些包本质上就是一个独立的 dbt 项目,所以我现在希望 A 项目下的所有 model 运行后创建的都是 view,而 B 项目 models 的 a 目录下所有 model 创建的都是 table,b 目录下创建的都是 view,我们可以在 dbt_project
文件中添加如下配置:
models:
A:
+materialized: view
B:
a:
+materialized: table
b:
+materialized: view
其实你已经发现了,与常规项目配置中以项目作为开头不同,dbt 是以 models
、seeds
这些特殊含义的字段作为开头,然后由项目到目录,由目录到具体文件对不同层级下不同文件定义不同的配置规则,因此如果你需要对 models
以及 seeds
做不同的配置,你完全可以定义类似如下的配置代码:
models:
A:
a:
+materialized: table
+schema: "{
{ 'mc_data_statistics' if target.name == 'dev' else 'details' }}"
+enabled: