设置您的 dbt 项目
通常,dbt 运行在云数据仓库之上,如 Snowflake 或 Google BigQuery。不过,为了简化本教程,我们将在本地连接到一个 DuckDB 数据库。
1. 先决条件
- 如果尚未安装,请在您的机器上安装 Python。
2. 安装必需工具
使用 pip 安装 dbt CLI:
pip install dbt-core
通过 pip 安装 DuckDB:
pip install duckdb
通过 pip 安装 DuckDB 适配器:
pip install dbt-duckdb
3. 初始化 dbt 项目
创建一个新的 dbt 项目:
dbt init project_name
该命令会在当前目录下创建一个项目,结构如下:
project_name/
├── analyses/
├── logs/
├── macros/
├── models/
├── seeds/
├── snapshots/
├── tests/
├── .gitignore
├── dbt_project.yml
4. 设置 DuckDB 连接
编辑 profiles.yml 文件(通常位于 ~/.dbt/ 文件夹)。如果不存在,请创建一个:
project_name: # This matches the name in dbt_project.yml file
target: dev
outputs:
dev:
type: duckdb
path: path/to/demo_database.duckdb
threads: 1
profiles.yml 包含指向 .duckdb 数据库文件位置的配置,您需要在 path 中指定。
您可以新建一个数据库,或从此处下载一个小型示例数据库。在下一节中,我将使用同一来源的 duckdb-demo.duckdb 文件。
要创建一个新的 DuckDB 数据库文件,只需运行以下代码:
import duckdb
duckdb.connect('/path/to/your/duckdb/database.duckdb')
5. 测试连接
现在,运行 dbt debug 测试一切是否正常。运行命令前请确保位于项目文件夹:
cd /path/to/your/project/
dbt debug
如果设置正确,您将看到类似如下的返回结果(为保护隐私,已对路径进行省略):
15:20:00 Running with dbt=1.9.1
15:20:00 dbt version: 1.9.1
15:20:00 python version: 3.11.5
15:20:00 python path: ...
15:20:00 os info: Windows-10-10.0.22631-SP0
15:20:00 Using profiles dir at ....
15:20:00 Using profiles.yml file at ...
15:20:00 Using dbt_project.yml file at ...
15:20:00 adapter type: duckdb
15:20:00 adapter version: 1.9.1
15:20:00 Configuration:
15:20:00 profiles.yml file [OK found and valid]
15:20:00 dbt_project.yml file [OK found and valid]
15:20:00 Required dependencies:
15:20:00 - git [OK found]
15:20:00 Connection:
15:20:00 database: demo_database
15:20:00 schema: main
15:20:00 path: ...
15:20:00 config_options: None
15:20:00 extensions: None
15:20:00 settings: {}
15:20:00 external_root: .
15:20:00 use_credential_provider: None
15:20:00 attach: None
15:20:00 filesystems: None
15:20:00 remote: None
15:20:00 plugins: None
15:20:00 disable_transactions: False
15:20:00 Registered adapter: duckdb=1.9.1
15:20:01 Connection test: [OK connection ok]
使用 dbt 创建语义层
恭喜您完成以上步骤!您已成功设置了第一个 dbt 项目。
现在,让我们看看如何在数据库之上创建语义层。为此,您可以将自己的 CSV 数据导入 DuckDB,或从这里下载一个小型(5MB)示例数据库文件。
然后,我们可以编写一个简单的 Python 脚本来探索该数据库文件包含的内容:
import duckdb
# Connect to the database
conn = duckdb.connect("duckdb-demo.duckdb")
# Get list of tables
tables = conn.execute(
"SELECT table_name FROM information_schema.tables WHERE table_schema='main'"
).fetchall()
print(f"\nNumber of tables in database: {len(tables)}")
print("Table names:")
for t in tables:
print(f"- {t[0]}")
print("\nTables in database:")
for table in tables:
print(f"- {table[0]}")
# Get schema for each table
schema = conn.execute(f"DESCRIBE {table[0]}").fetchall()
print("\nSchema:")
for col in schema:
print(f" {col[0]}: {col[1]}")
# Preview data
data = conn.execute(f"SELECT * FROM {table[0]} LIMIT 5").fetchall()
print("\nFirst 5 rows:")
for row in data:
print(f" {row}")
print("\n---")
# Close connection
conn.close()
输出(为简洁起见已截断):
Number of tables in database: 17
Table names:
- bank_failures
- boxplot
- calendar
- ...
Tables in database:
- bank_failures
Schema:
c1: BIGINT
Bank: VARCHAR
City: VARCHAR
State: VARCHAR
Date: DATE
Acquired by: VARCHAR
Assets ($mil.): DOUBLE
First 5 rows:
(1, 'Douglass National Bank', 'Kansas City', 'Missouri', datetime.date(2008, 1, 25), 'Liberty Bank and Trust', 58.5)
(2, 'Hume Bank', 'Hume', 'Missouri', datetime.date(2008, 3, 7), 'Security Bank', 18.7)
...
…
该数据库包含 17 张表。但在本教程中我们仅使用 bank_failures 表。该表包含美国失败银行的历史财务细节。
1. 定义 SQL 模型
SQL 模型是任何 dbt 项目的基础。它们代表将原始数据结构化转换为更适合分析的格式。
在本教程中,我们将在 models/ 文件夹下定义两个 SQL 文件。
在项目的 models 文件夹中新建一个名为 base_bank_failures.sql 的文件:
SELECT *
FROM bank_failures
该文件直接从 bank_failures 表提取原始数据,作为基础模型,后续模型可引用。
随后,新建另一个名为 clean_bank_failures.sql 的文件:
SELECT
State,
COUNT(*) AS total_failures,
SUM("Assets ($mil.)" ) AS total_assets
FROM
{{ ref('base_bank_failures') }}
GROUP BY
State
该文件基于 base_bank_failures 模型(使用 ref() 函数)进行聚合与清洗,为分析做准备。它按州汇总失败次数与资产。
2. 创建 metrics.yml 文件
metrics.yml 用于定义集中、可复用的指标,确保在分析与仪表板中的一致性。
在我们的场景中,它将描述如 total_assets 与 avg_assets_per_failure 等指标,使其可被 BI 工具与其他查询直接使用:
version: 2
models:
- name: clean_bank_failures
description: "Aggregated data about bank failures."
columns:
- name: State
tests:
- unique
- name: "Assets ($mil.)"
metrics:
- name: total_assets
label: Total Assets
type: sum
expression: "Assets ($mil.)"
description: "Total assets of failed banks, aggregated by state."
- name: avg_assets_per_failure
label: Average Assets per Failure
type: average
expression: "Assets ($mil.)"
description: "Average assets for each bank failure."
3. 创建 exposures.yml 文件
exposures.yml 将您的 dbt 模型关联到 Tableau 或 Looker 等外部工具。它记录这些连接,确保可追溯与一致性。
该文件指定 clean_bank_failures 模型被一个 Tableau 仪表板使用,并提供负责人与依赖的详情:
exposures:
- name: tableau_dashboard
type: dashboard
url: https://tableau.yourcompany.com/workbook
owner:
name: Data Team
email: datateam@yourcompany.com
depends_on:
- ref('clean_bank_failures')
构建与测试语义层
要成功验证并构建您的 dbt 项目,可使用以下常用命令:
1. 构建模型: 运行 dbt build 以实体化所有模型、执行测试,并运行 seeds 与 snapshots。该命令合并了 dbt run 与 dbt test 的功能:
dbt build
2. 测试模型: 如果只想在构建后用测试验证数据,请使用 dbt test。它会对模型应用所有数据质量测试(例如唯一性与非空检查)。
dbt test
3. 运行特定模型或测试: 若只需运行特定模型或测试,可将其名称作为参数。例如,仅运行某个模型:
dbt run --select clean_bank_failures
测试某个特定列:
dbt test --select clean_bank_failures.State
将语义层与 BI 工具集成
要将 dbt 连接到 Looker 或 Tableau 等 BI 工具,请遵循以下步骤,有效暴露语义层并确保 BI 工具可直接引用 dbt 模型与指标:
1. 在 dbt 中启用 exposures
在 dbt 项目的 models 文件夹下创建 exposures.yml 文件,内容如下:
exposures:
- name: tableau_dashboard
type: dashboard
url: https://tableau.yourcompany.com/workbook
owner:
name: Your Name
email: email@yourcompany.com
depends_on:
- ref('clean_bank_failures')
2. 准备数据库连接
- 确保转换后的数据模型已在您的数据库(如 Snowflake、BigQuery、DuckDB)中可用。
- 运行
dbt build将 dbt 模型实体化到数据库中。
3. 将 Tableau 连接到 dbt 模型
- 打开 Tableau Desktop,创建到数据库的新连接。
- 选择存放 dbt 模型的架构(schema)。
- 将 dbt 模型(例如
clean_bank_failures)拖放到 Tableau 工作区。
4. 在 Tableau 中定义指标
- 在 Tableau 中直接使用 dbt 定义的指标(如
total_assets或avg_assets_per_failure)进行可视化,以确保一致性。 - 如有需要,可创建计算字段以增强可视化效果。
5. 将 Looker 连接到 dbt 模型
- 在 Looker 中进入管理面板,设置到数据库的连接。
- 为每个 dbt 模型创建一个 LookML 视图,导入其架构与字段。
- 使用 dbt 中定义的
total_assets或avg_assets_per_failure指标,构建一致的 Looker Explore 与仪表板。
使用 dbt 实现语义层的最佳实践
既然您已了解用 dbt 构建语义层的流程,让我们回顾一些最佳实践。
集中业务逻辑
在 dbt 中定义所有业务规则,以确保一致性与可维护性。通过集中业务逻辑,您可消除跨工具的冗余定义,打造一个所有相关方都能轻松更新与理解的单一真实来源。
模块化模型
将转换拆分为逻辑清晰、可复用的组件。例如,为原始数据创建基础模型,为清洗与转换后的数据创建中间模型,为可直接用于分析的数据创建最终模型。
这种模块化结构便于排错、促进代码复用,并让团队成员能够在不干扰整个管道的情况下各自处理组件。
全面记录
利用 dbt 的自动文档,让您的语义层始终井然有序、透明可查。
在 YAML 文件中为模型、指标与列添加清晰的描述。
定期更新文档以反映变化,并使用 dbt 自动生成的血缘图来可视化模型之间的关系。这样可确保语义层对所有用户都易于访问与导航。
像 dbt-utils 包 这样的工具可显著简化您的 dbt 工作流,提供预构建的宏与工具,帮助简化模型开发并确保完善的文档。
结语
使用 dbt 实现语义层,是弥合原始数据与可行动洞见之间差距的有力方式。dbt 的模块化数据建模、集中化指标定义、稳健的版本控制以及与 BI 工具的集成,能够帮助您为分析与报告提供一致、可靠且易用的数据。
本教程带您完成了设置 dbt 项目、创建 SQL 模型、定义可复用指标,以及将语义层与 Tableau、Looker 等可视化工具集成的全过程。
如需进一步了解 dbt,请查看优秀的 《Introduction to dbt》课程!

许多现代公司依赖语义层来弥合存储在数据仓库(如 Snowflake)中的原始数据与仪表板或报告中的洞见之间的差距。
语义层是一种抽象,用于为分析和报告定义一致的指标、度量和维度。
在本教程中,我们将探索如何使用 dbt(data build tool) 实现语义层,这是一种流行的数据转换与建模框架。本文包含实用示例与要点,帮助您深入掌握这一概念。
什么是语义层?为什么重要?
语义层将原始数据转换为一致、可复用的指标与维度,简化数据分析。它有助于在团队与工具之间保持统一。
语义层的优势
为何 dbt 适合构建语义层
让我们看看 dbt 如何成为数据与分析工程师构建语义层的理想工具。
dbt 语义层概念图,由 dbt Labs 提供
模块化数据建模
dbt 允许将复杂的数据转换拆分为可复用的模块化模型。这些模型可按层次构建,基础数据模型为更高层的分析模型提供输入。
这种方法让数据管道更易维护,并通过将变更隔离到特定模型而不影响整个系统,从而提升团队协作效率。
如需进一步了解 dbt 的基础概念与数据建模最佳实践,请参阅《dbt 教程:数据工程师必知的 7 个概念》。该教程提供的见解与本文策略相辅相成。
集中化指标定义
借助 dbt,可在同一处定义业务逻辑与指标,确保在各类分析工具中的一致性。利用 dbt 的 metrics 功能,您可以一次性定义营收、转化率或流失等 KPI,并在各类仪表板、报告与分析中复用,无需重复定义。这降低了差异并确保数据完整性。
版本控制与文档
dbt 与Git 集成,提供强大的版本控制,便于跟踪与审计历史变更。结合其自动生成的文档,dbt 为所有数据转换与指标创建了一个可访问的动态参考库。这样既提高透明度,也便于新成员通过浏览已记录的数据管道快速上手。
与 BI 工具集成
dbt 可与 Looker、Tableau、Mode 等 BI 平台协作,将语义层集成到可视化工具中。借助 dbt exposures,您可以将 dbt 模型直接关联到 BI 仪表板,确保数据模型的任何更新都能自动反映到分析中,无需手动介入。