2. dbt项目初始化与工程结构
dbt 项目不是一个散落的 SQL 文件夹,而是一个有明确约定的工程单元。理解它的初始化方式和目录结构,是后续做模型分层、测试、文档和部署的前提。本节围绕 dbt init、项目目录、dbt_project.yml、profiles.yml 以及包管理与版本控制集成展开,目标是让你能独立创建一个可运行、可协作、可版本化的 dbt 项目。
一、用 dbt init 创建项目骨架
在安装好 dbt 适配器(例如 dbt-postgres、dbt-snowflake、dbt-bigquery)之后,执行初始化命令:
dbt init my_first_project
cd my_first_project
执行过程中,dbt 会交互式询问目标数据库类型、连接参数(host、port、user、password、database、schema 等),并把连接信息写入 ~/.dbt/profiles.yml。项目本身则生成在当前目录下。初始化完成后,可以用 dbt debug 验证连接是否可用:
dbt debug
# 输出中应看到 Connection test: [OK connection ok]
如果 dbt debug 报错,优先检查 profiles.yml 中的 profile 名称是否与 dbt_project.yml 里的 profile 字段一致,以及环境变量是否已导出。这一步是后续所有命令能跑通的基础。
二、项目目录结构
一个标准 dbt 项目包含以下核心目录与文件:
dbt_project.yml:项目主配置,定义项目名、版本、profile、模型路径、物化策略等。models/:存放所有 SQL 模型,通常按staging/、intermediate/、marts/分层。seeds/:存放 CSV 静态数据,用dbt seed加载为表。snapshots/:存放快照 SQL,用于记录维度表的历史变化(SCD2)。tests/:存放自定义数据测试 SQL。macros/:存放可复用的 Jinja 宏。analyses/:存放不物化、仅编译的 SQL 分析文件。packages.yml:声明外部 dbt 包依赖。README.md、.gitignore:协作与版本控制配套文件。
其中 target/ 和 dbt_packages/ 是运行产物,必须加入 .gitignore,不要提交到仓库。
三、dbt_project.yml 的关键配置
dbt_project.yml 是项目的“总控文件”。一个最小可用示例如下:
name: 'my_first_project'
version: '1.0.0'
profile: 'my_first_project'
model-paths: ["models"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
test-paths: ["tests"]
models:
my_first_project:
staging:
+materialized: view
+schema: staging
marts:
+materialized: table
+schema: marts
这里 +materialized 表示对该目录下所有模型统一设置物化方式,+schema 表示统一写入指定 schema。这种“目录级默认值 + 模型级覆盖”的机制,是 dbt 工程化管理的核心。例如某个模型需要单独改成增量物化,只需在模型文件顶部写 {{ config(materialized='incremental') }} 即可覆盖目录默认值。
四、profiles.yml 与连接管理
profiles.yml 默认位于 ~/.dbt/,用于存放数据库连接信息。它按 profile 名称组织,每个 profile 下可定义多个 target(如 dev、prod):
my_first_project:
target: dev
outputs:
dev:
type: postgres
host: localhost
port: 5432
user: dbt_user
password: "{{ env_var('DBT_PASSWORD') }}"
dbname: analytics
schema: dbt_dev
threads: 4
prod:
type: postgres
host: prod-db.internal
port: 5432
user: dbt_prod
password: "{{ env_var('DBT_PROD_PASSWORD') }}"
dbname: analytics
schema: dbt_prod
threads: 8
注意两点:第一,密码不要明文写入,使用 env_var() 读取环境变量;第二,profiles.yml 不应提交到项目仓库,它属于个人或部署环境配置。切换环境只需 dbt run --target prod。
五、包管理与版本控制集成
dbt 包用于复用社区或团队内部的模型、宏和测试。在 packages.yml 中声明依赖:
packages:
- package: dbt-labs/dbt_utils
version: [">=1.0.0", "<2.0.0"]
- package: calogica/dbt_expectations
version: 0.10.3
- git: "https://github.com/your-org/dbt-shared-macros.git"
revision: v1.2.0
然后执行 dbt deps 安装。安装后的包位于 dbt_packages/,同样不应提交。版本控制方面,建议:
- 用 Git 管理项目,
.gitignore中排除target/、dbt_packages/、logs/、.user.yml。 - 提交
packages.yml和package-lock.yml(dbt 1.7+ 生成),锁定依赖版本,保证团队环境一致。 - 分支策略上,模型变更走 feature 分支 + PR,CI 中运行
dbt build --select state:modified+只构建变更模型及其下游。
dbt run 和 dbt test,确认示例模型能跑通,再开始替换为自己的业务模型。六、工程结构关系图
下图把项目初始化后的关键对象、配置来源与依赖关系集中呈现,便于对照理解各文件之间的作用边界。
把这张图当作项目初始化后的检查地图:左侧是命令入口,中间是项目目录与配置文件,右侧是连接配置,下方区分了“提交 Git”与“运行产物”的边界。只要 dbt_project.yml 的 profile 名称与 profiles.yml 对应、packages.yml 已执行 dbt deps、.gitignore 排除了产物目录,这个项目就具备了团队协作和持续集成的基础条件。