深入解锁 dbt——dbt 入门

0 阅读1小时+

2006 年,英国数学家、数据科学领域企业家 Clive Humby 提出了 “Data is the new oil” 这句话,意思是“数据是新的石油”,因为数据拥有极高的价值。虽然数据和石油在原始状态下都有价值,但它们都必须先经过 processing,才能创造真正有价值的东西。原油会被送到炼油厂,在那里被分离成 fuel、oils、asphalts 等 petroleum products,进而成为日常生活中的基础资源。Data 则会被 people、tools 和 services 精炼为 reports、data warehouses、machine learning models 等,以提取其价值。无论是 data 还是 oil,如果只是让它停留在 raw form,那就只是一种被浪费的机会。

从我们能记住的过去,到我们能预见的未来,data 都会一直重要。对许多公司来说,它们的数据价值甚至被估算为超过公司本身的价值。这也是为什么 data 不仅是 tech 领域最热门的方向之一,也是所有行业中最热门的方向之一。对 skilled workers 的需求已经超过 available talent pool,这使得一些公司不得不尝试自己培养人才,或者缩减一些重要 initiatives。今天市场中表现强劲的 data tools 和 services,都是那些能够发挥大多数 data professionals 优势的工具,而不是迫使他们学习一整门新的 programming language,尤其是在学习新语言并不能带来显著优势时。

这正是我们作为本书作者喜欢 dbt 的地方。任何 data professional 都需要具备的一项核心技能,就是编写 SQL,而 dbt 将 SQL 作为自己工作的核心。因此,虽然 dbt 是一个相对较新的工具,但对于任何熟悉 SQL 编写的 data professional 来说,它的 learning curve 都很小。本章将作为整本书其余部分的 introduction。本章会覆盖 dbt 是什么、它适合谁、它如何融入你的 data stack 等内容。我们还会对产品做一个 high-level overview,介绍一些本书后续会反复使用的 fundamental terminology。本章会覆盖很多内容,所以如果你读完后感觉有些迷失,不用担心,因为本书其余部分会深入讨论与 dbt 相关的具体主题,让你学会开始使用 dbt 所需的一切。我们希望先给你一个 big picture 的概览,然后在后续内容中一步一步拆解每个 component。

What Is dbt?

用最简单的定义来说,dbt,或者 data build tool,是一种 open source data transformation tool,常用于在 data warehouses 中进行 data modeling。它使那些熟悉 SQL 编写的 data professionals 能够更有效地转换 warehouse 中的数据。更细一点说,它是一个带有 development framework 的工具,将 modular SQL 与 software engineering best practices 结合起来,从而创造更好、更快、更可靠的 data transformation experience。Modular SQL 指的是将 SQL code 拆分为更小、可复用的代码块,使其更容易维护、测试和复用。dbt 也很好地支持其他 best practices,包括 version control、documentation、DevOps 等。

不过,非常重要的一点是:dbt 只是一个 transformation tool,它并不处理其所连接 data store 之外的数据移动。因此,当你考虑 extract-transform-load(ETL)和 extract-load-transform(ELT)设计时,dbt 只负责这些 patterns 中的 transform component。你需要将 dbt 与其他工具结合起来,才能创建完整的 ETL / ELT pipelines。市场上有一些工具,例如 Fivetran、Airflow 和 Meltano,允许你把 dbt 作为它们 framework 的一部分运行;你也可以使用完全独立的工具。如何使用 dbt,取决于你自己,以及什么最适合你的 use case。

Note

dbt 只是一个 data transformation tool,需要与其他 tools / services 结合,才能创建完整的 ETL / ELT pipelines。

大多数 Data Engineering tools / services 都像 software engineering tools 一样构建,因此许多 best practices 对它们来说是 native 的。但对于 Data Analysts 及其常见 workflows 来说,情况并不总是如此。我们知道 job titles 对不同人可能意味着不同内容,所以这里先澄清一下我们所说的 Data Analyst:它指的是那些负责 gathering 和 interpreting data,以便为 business 解决 specific problem 的人。正如 title 所暗示,他们负责 analyzing data。通常,他们也可能负责 creating reports,但这只是该角色的一部分。他们大量工作时间会用于编写 SQL queries,以理解和建模数据,从而回答 specific questions。Data Analyst 可以使用 views 和 / 或 stored procedures 来保存代码,但即便如此,仍然需要其他工具与之结合,而这些工具往往更偏向 SQL development。此外,在 database 中创建 objects 通常会被 administrators 严格管控,并且往往需要适当 controls 到位。多年来,data 工作中的这个领域一直被忽视,而这正是 dbt 最初被创建的主要原因。

dbt 于 2016 年由一家名为 Fishtown Analytics 的公司创建,该公司后来在 2020 年更名为 dbt Labs。Fishtown Analytics 是一家位于费城 Fishtown 街区的 analytics consulting company,成立之初是为了帮助 A 轮和 B 轮 venture-funded companies 实施 advanced analytics。具体来说,他们希望改进 Data Analysts 的工作方式。他们认为 data analysis 应该以一种更接近 software engineering 的方式来实践,并试图为此找到解决方案。由于市场中存在空白,他们创建 dbt 来填补这一缺口。有趣的是,dbt 最初是一个 open source solution,用于为 Stitch 添加 basic transformation capabilities,但它的愿景远不止于此。Fishtown Analytics 在更名前构建了一个付费版本工具,名为 Sinter,为 users 提供额外功能,包括 scheduling、logging、alerting 等。2019 年,这个工具更名为 dbt Cloud,其功能迅速发展为今天的样子。dbt Core 和 dbt Cloud 目前都仍然可用,并且会在本书中被深入覆盖。

Open source 部分,也就是 dbt Core,是运行 dbt 所需的 codebase。你需要自己的 tools 和 infrastructure 来运行它,但可以免费使用该 codebase,即使其他组件会产生费用。即便你不使用 dbt Core,而选择使用付费版本 dbt Cloud,也仍然能对 codebase 拥有一定控制权。你可以修改 macros 和其他一些 features,从而影响 default behavior,但不能像使用 Core 那样改变一切。dbt Cloud 中还有一些非 open source components,特别是与 integrated development environment(IDE)、scheduling、jobs 等相关的部分。我们会在本章稍后做 high-level 介绍,并在第 2 章中更详细讨论。

如前所述,dbt 是一个 data transformation tool,但它不同于市场上的其他工具。关于 dbt,我们认为有几个重要点需要你在早期就理解:

  1. dbt 不包含执行 models 所需的 computation,它依赖 warehouse / database 的 compute。
  2. 除 Python models 外,你在 dbt 中构建的每个 model 都写成 SQL select statement,并且无论是否使用 Jinja,最终都会 compile 成 SQL statement。
  3. dbt 会替你处理 database object creation,例如 tables、views 等,因此不需要提前创建这些 objects。

首先,虽然 dbt 只是一个 transformation tool,但它在任何产品形态中都不包含执行 statements 所需的 compute power。dbt 针对 warehouse 查询和构建的所有内容,都会使用 warehouse 的 compute power。例如,如果你使用 AWS Redshift 作为 data warehouse 或 data store,那么 dbt 会使用 AWS Redshift 的 compute cluster 来构建 models。dbt 没有用于处理 data processing 的 computing mechanism,我们也不认为这一点会改变。使用 dbt Cloud 进行开发和调度 dbt jobs 时,确实需要少量额外 compute,并且这部分已包含在服务中,但它不使用你的 warehouse compute。不过,如果你使用 dbt Core 开发,在设计 infrastructure 时就需要考虑这一点。此外,正如前面提到的,dbt 没有 extract 和 load data 的能力,因此 data 必须已经存在于你要对其执行 transformation 的同一个系统中。所以,如果你使用 AWS Redshift 的 compute,那么在针对 data 运行 dbt models 之前,你需要让 data 已经存在于 AWS Redshift 中。

第二,需要理解的是,你在 dbt 中创建的每个 model 都会 compile 成一条 SQL statement,并在 warehouse 上运行。唯一例外是 Python models,但我们会在第 4 章中详细介绍。dbt 会将 Jinja 加入你的 SQL 中使用,这可以非常强大且高效,但最终它仍然只是转换为 SQL code。我们会在本章稍后讨论 Jinja,并在第 6 章中深入讲解;现在你只需要知道 Jinja 是一种 templating language。有趣的是,你构建的每个 model 也必须写成 SELECT statement。如果你习惯自己编写 data manipulation language(DML)statements,例如 UPDATE、INSERT、MERGE 和 DELETE 来修改已有 database objects,这一点需要适应。不过,根据你的 model type,dbt compiler 会添加管理 database objects 所需的任何 DML 或 DDL(data definition language)boilerplate code。我们会在第 4 章深入讨论这一点。

这里想强调的最后一个大组件是:dbt 也会替你在 warehouse 中处理 object creation。如果你过去使用过 data warehouses,可能习惯先创建 schema objects 再执行 transformations,但现在不再需要这样做。虽然你仍然可以这么做,但我们始终建议不要采用这种 anti-pattern,而是推荐使用 dbt 创建 objects。如果你不想让 data types 被自动推断,仍然可以控制 data types,但需要通过代码完成,例如使用 CAST commands。

The Analytics Engineer

如果你在 dbt 周围花过不少时间,就不可避免会听到 Analytics Engineering 这个术语。这是 dbt team 采用的一个术语,用于标记 dbt users 所做的事情。Analytics Engineers 是传统 Data Engineer 与 Data Analyst 的结合。他们向 business users 提供 modeled 和 clean datasets,供其消费数据。Data Analysts 通常把时间花在 analyzing data 上,而 Data Engineers 把时间花在 building infrastructure、extracting、loading 和 transforming data 上。借助 dbt 的力量,Analytics Engineer 将这些元素结合起来,并使用自己熟悉的技能,从 Data Analytics 架起通往 Data Engineering 的桥梁。Claire Carroll 在 dbt 网站上写过一篇博客,很好地概述了 Analytics Engineering 是什么。在文中,她列出了自己对 Data Engineers、Data Analysts 和 Analytics Engineers 区别的看法。图 1-1 突出了她在文章中提到的一些内容。

image.png

图 1-1:Analytics Engineer 视图

作为本书作者,我们喜欢 Analytics Engineering 这个角色,但并不认为它有什么革命性。我们更倾向于把它看作一种优秀的 marketing strategy,用一个独特名称来标记 dbt users。不过,dbt 确实为处于 Analytics Engineer 角色中的人提供了更快交付价值的 toolset。过去那种必须等待 Data Engineering team 实现简单 transformation 的日子已经过去了。不同组织中的 job titles、roles 和 responsibilities 可能差异很大,而 Analytics Engineer 这个角色很容易与 Data Engineer 或 Data Analyst 连接起来,并且我们认为这种连接是合理的。Analytics Engineering 取了这两个角色传统上相关的部分,并将它们结合起来。公司,尤其是小团队,其实几十年来一直在做类似的事,而 dbt 提供了一个平台,让这件事更高效。我们说这些并不是负面评价。这个新 title 已经获得大量关注,提升了 brand awareness,并为 dbt users 提供了一个可连接的标签,这是一件好事。

我们也觉得 dbt 被非常强烈地 marketing 给 Data Analyst community,而理解其市场后,这很合理。dbt 最初就是为了将 software engineering best practices 引入长期被忽视的 Data Analyst 角色而创建的。我们完全相信这一点,但也想说明,dbt 同样是一个 Data Engineering tool,而且是一个非常好的 Data Engineering tool。我们认为这一点没有得到应有的市场关注,因为对于任何负责使用 SQL 或 Python 建模数据的人来说,它都是一个出色的 Data Engineering tool。至于原因,我们认为归根结底是 money,而不是 product usability。dbt Labs 通过 dbt Cloud subscribers 赚钱,而大多数 Data Engineers 会很舒服地使用免费且 open source 的 dbt Core,很多人也确实这么做;相比之下,Data Analysts 不太可能有兴趣管理 dbt Core deployment。虽然这是真的,但我们仍然觉得这里有一些 missed opportunity。本书两位作者都更偏 Data Engineering 这一侧,而 dbt 是我们最喜欢用来构建 data products 的工具之一。即便我们以及许多其他 Data Engineers 都能舒服地运行 dbt Core,我们也和很多 Data Engineers 交流过,他们同样喜欢 dbt Cloud,因为它部署起来很容易。

Note

dbt 不只是 Data Analysts 的工具,它也是一个非常出色的 Data Engineers 工具。

The Role of dbt Within the Modern Data Stack

在理解 dbt 的角色之前,我们应该先理解 ELT(extract-load-transform)builds 的重要性。这里我们排除了 ETL(extract-transform-load),因为大多数 cloud architectures 并不采用这种方式,不过下面的说法对 ETL 同样成立。由于现代 analytical databases 的强大能力,ELT 已经在许多 warehouse designs 中变得很常见。Snowflake、Synapse、Databricks 和 BigQuery 等现代 cloud data warehouses 更快、更 scalable,并且完全能够在 database level 处理 transformations。考虑到 Snowflake 和 Lakehouse architectures 等系统中的 storage 和 compute 分离,这一点尤其成立。

ELT models 在 cloud services 中流行的一个主要原因,是 network latency 和 transfer data 所需时间。虽然 network speeds 已经很快,并且还在持续变快,但 data volumes 也在持续增长。所以,如果你处理的是需要通过 Internet 传输的大量数据,仍然可能需要相当长时间。因此,你希望确保 data 只需要 load 一次。为了简化说明,假设我有十张 tables,总计 100GB,需要从 on-premise database server 传输到 AWS S3 bucket,并且这需要五个小时。如果我在其中添加 transformations,也就是 ETL setup,然后发现自己做错了,就必须全部重做。或者,如果一个月后,我使用这些 data 的 requirements 发生变化,那么我需要重新 load 一次这些 data,以及这段时间里新增的所有 data。将这种情况扩展到越来越多的 source systems,你很快就会发现自己在浪费大量时间。如果我们一开始只 load raw data,也就是 ELT,就只需要 load data 一次。是的,你实际上是在存储一份额外的 source data copy,ingestion 时做 transformation 可以减少这一点,但 cloud 中 storage 非常便宜,对大多数人来说,这不应该是问题。Raw data 落地后,你就可以更快地处理它;如果出错,也可以轻松调整,甚至重新开始,这会节省大量时间。此外,当新项目也需要使用这些 data 时,就不必重新拉取数据,从而有效减少 storage footprint 和时间。

Note

dbt 不仅限于构建 data warehouse,也可以用于支持其他 reporting 和 analytical workloads,即使这些场景不一定需要 data warehouse。不过 data warehouse 是本书的重点。

因此,在 data warehouse ELT architecture 中,让我们看看与其相关的 high-level steps,以及 dbt 如何完成这些内容。图 1-2 展示了 data warehouse build 中常见项目的 diagram。无论你是否使用 dbt 作为 transformation tool,这些仍然都是你在任何选型工具中应该关注的内容。

image.png

图 1-2:ELT data warehouse design 的 high-level steps

构建 ELT warehouse 的第一步,是定义和配置 data loader。Data loader 用于开发 ingestion pipelines,将 data 从 sources 进入 warehouse environment。你可以选择任何工具。如前所述,dbt 只是一个 data transformation tool,因此这个 component 超出了它的使用范围;不过,在你使用 dbt 之前,它仍然是一个非常重要的 component。如果你不确定从哪里开始或选择什么工具,我们建议联系你所使用 data warehouse 的 vendor,并获取他们的反馈。有些 ingestion tools 能很好地集成到他们的系统中,并可能提供额外优势,而有些可能完全不适合。此外,所有主要 cloud providers 都有自己的工具可用于这个目的,例如 Azure Data Factory、AWS Glue、Google Cloud Data Fusion 等,但不要忽视 third-party tools,因为市场上确实有一些非常出色且易用的工具。有些工具,例如 Fivetran,拥有 native connectors,可以无缝复制 source data 到 warehouse,并减少这部分流程中的大量 development time 和工作。只要确保在这里做足 due diligence,认真评估所有选项,因为这可能决定项目成败。

选定并设置 data loader 后,就可以开始 loading raw data。正如前面讨论的,将 raw data ingest 到 warehouse 中,并且永远不要修改它,非常重要。这样,data 可以被多个用途共享,任何处理 data 时犯下的错误都可以轻松解决,而不需要再次 ingest data。选择将 data load 到哪里,是另一个需要做出的决定,并且会很大程度取决于你的 architecture。有些 designs 会先将 data load 到 storage account,通常称为 data lake;有些 designs 则会直接将 data load 到 data warehouse。两种都可以,但要知道,如果你使用 dbt 作为 data transformation tool,raw data 需要存在于你执行 transformation 的同一系统中。因此,如果你先将 data load 到 data lake,但 dbt 指向的是 AWS Redshift instance,那么在使用 dbt 之前,也需要先把 data stage 到 Redshift 中。当然,你也可以直接把 raw data copy 到 Redshift,这也能工作,但有一些本书范围之外的原因,可能让你不想这么做。作为本书作者,我们强烈建议评估 lakehouse designs 或 Snowflake 作为潜在方案,并将 raw data 直接落到这些平台中。Storage 和 compute 分离是使用这些平台的巨大优势。无论你如何决定,只要知道一点:raw data 必须存储在你计划使用 dbt 做 transformation 的同一位置。

现在 raw data 已经落到 data store 中,就可以开始 processing。Processing 的第一步,是 snapshot raw data,不要与 dbt 中的 snapshot features 混淆。我们永远不希望修改 raw data,因为任何错误都可能导致我们需要重新 ingest data,或者如果 ingestion process 中包含 history tracking,还可能造成不可修复的损害。相反,我们可以对 data 做 snapshots。这意味着从 raw data objects / tables 中拉取需要的数据,开始处理它。如何存储它,例如 table、view、common table expression(CTE)等,以及如何使用它,取决于你的 model 设计,因此不同组织可能不同。这个步骤也不是互斥的,可以与下一步 action,包括 transformations,结合在一起。作为作者,我们喜欢 snapshot raw data,并将 initial transformations 与之结合,然后 load 到 warehouse 的 staging table 中。我们也会加入 incremental logic,确保每次只 extract 和 transform new and changed data,而不是 full dataset。不过,这仍然基于你如何设计 warehouse。dbt 使读取 raw data 变得非常简单,这也是本书会详细覆盖的主题。

下一步是 transform data,使其适配你的 data model。这意味着通过 normalizing / denormalizing、cleaning 和 modeling,为 analytics、machine learning 等重塑数据。这是在把来自不同系统、原本为某种数据处理方式而设计的数据,例如 transactional systems,完全转变为针对 reporting 和 analytics 优化的形式。这就是 dbt 的核心,也是你选择使用它的原因。如何 transform data 会因你构建 data model 的方式而有很大差异。本章下一节会看看你可以选择的常见 data model types。

Data 被 transform 后,你需要通过 performing tests 验证 data 是否 accurate。Accuracy 是任何 analytical 或 reporting role 中最重要的组成部分,尤其是在构建 enterprise data warehouse 时,因为这些 data 会在整个组织中共享。很多时候,我们从 transactional systems 等系统中拉取 data,而这些系统是为完全不同的目的构建的,因此必须做大量 transformations 来 model 和 clean data,这就创造了犯错机会。Testing data 可以确保你没有无意中改变 data 的含义,并且 data 按预期方式 modeled。很多时候 testing 发生在 transformation process 之外,这并不理想,因为等你发现问题时,损害已经发生。幸运的是,dbt 将 testing 纳入 transformation pipelines。这是 dbt 的巨大优势之一,我们会在本书第 8 章详细介绍。

下一项是 deployment。你不应该直接在 production 上开发,因此需要一种安全、高效、快速的方法,在 environments 之间移动经过测试的代码。虽然可以手动完成,但多数 engineers 希望有一种自动化方式,因此他们通常会看向 CI/CD(Continuous Integration / Continuous Deployment)等 DevOps processes。有多个 cloud-based 和 third-party tools 可以用于此,例如 Azure 中的 Azure DevOps,但 dbt Cloud 使你能够在单一工具中轻松处理这些事情。在第 10 章中,我们会介绍如何在 dbt Cloud 中运行 CI jobs,以及 dbt Core users 如何在 GitHub Actions 中运行 CI jobs。

代码被 developed、tested 和 deployed 后,下一阶段是 documentation。Documentation 是一个经常被忽视的组成部分,只有在它被明确设为 priority 时才会被处理,而很多时候并不是这样。然而,它是任何成功 data warehouse project 的重要方面。许多 technical professionals 抱怨这一部分,因为 technology 变化太快,documentation 很快就过时,而且反正没人使用。有一些 tools 通过自动化部分工作来帮助解决这个问题,但它们通常意味着你需要额外付费和管理另一个 service。借助 dbt,你可以在构建时为 objects 添加 descriptions,dbt 会将这些内容与 project metadata 结合起来,并放进一个易于理解的网站中。Documentation 通过运行一条简单的 dbt command 就可以刷新,因此你永远不需要担心手动更新 documentation。作为本书作者,我们喜欢这个 component 内置在我们开发时使用的工具中,而不需要花大量时间维护 documentation。我们会在本书第 9 章详细探索 dbt 中的 documentation。

在整个 warehouse 中 refining data 时,还有其他 components 需要考虑,例如引入 software engineering best practices。在 data pipelines 中,我们需要对代码进行 version / source control,需要对 processes 进行 alerting,也需要 logging 来识别问题。这些在许多 enterprise software engineering tools 中都很常见,dbt 也不例外。

一切构建完成后,你就拥有了最终 transformed data,可以将 data 提供给 business 或其他 data teams 使用。这些 data 可以被 data science teams、data analytics、reporting teams 等使用。

当你考虑使用什么工具以及如何构建 data warehouse 时,所有这些 components 都应该成为你评估的因素和考量。俗话说,“剥茄子有很多种方法”(我们喜欢猫),所以你可以用很多 solutions 成功实现目标,我们也不会说 dbt Cloud 是唯一方式。

Modeling Your Data

dbt 很棒,也确实简化了许多 transform data 所需的步骤。但就像任何 development tool 一样,如果你不战略性地使用它,它很快就会变成狂野西部。如果你使用 dbt 构建 data warehouse,或者构建用于 shared purposes 的 pipelines,仍然需要认真考虑希望如何 model data。不做决定,本身也是一种决定。如果你只是将它作为一个工具,帮助 analysts 存储和使用代码,那么仍然需要思考 project structure、naming conventions 等内容。但在本节中,我们会聚焦于你可以用哪些不同方式 model data。dbt 对你如何 model data 是 agnostic 的,它并不关心你怎么做。即使你的业务无法在混乱中运行,dbt 仍然会继续工作。

Note

dbt 对你如何 model data 是 agnostic 的,因此决定权在你手里,你需要选择最适合支持 business 的方式。

在开始之前,应该先确定是否真的需要 data warehouse。并不是每个场景都需要它,如果你还没有想清楚,在开始之前认真思考这一点很重要。以下问题中,只要有任何一个答案为 yes,就可能意味着你会从创建 data warehouse 中受益:

  • 是否重要的是为 data 建立 single source of truth?
  • 业务中的多个领域是否会消费这些 data?
  • 我们是否需要分析来自不同 sources 的 data?
  • 我们是否需要维护 data 的 historical tracking,并确保正在查看某一时间点的 measurables?
  • 是否有大量 data 需要 transform?
  • 你是否经常运行大量 complex queries?

如果这些问题中任意一个回答为 yes,那么如果你还没有 data warehouse,就可能需要考虑投入时间和资源构建一个。如果确定需要它,就需要评估计划如何结构化你的 data。

我们看到的 dbt 最大错误之一,是在没有 plan 的情况下把 dbt 交给 analysts 和 developers,然后让他们自由发挥。如果只是 ad hoc purposes,而且产出的内容只与 developer 自己相关,这可能没问题。但如果你构建的是 intended to be used at an enterprise level 的 systems,这会制造问题。最常见的问题包括重复工作、多版真相、低效 queries,以及难以将知识转移给团队其他成员。我们认为你仍然需要围绕所构建的内容制定 strategy。dbt 很棒,但它不是 magic,或者说它是 magic,但不是所有方面都是。如果是 data warehouse 或只是 data analytics,都需要有计划,并围绕要构建的内容创建 structure。如果你认为 data warehouse 适合你的需求,就需要确定你打算如何处理 data model。有很多 data warehousing approaches,每种都有 pros / cons,你需要根据 business need 决定哪种最适合。虽然本书不会覆盖如何为 data warehouse 选择 data modeling approach,但我们会列出一些最常见的 model methodologies:

  • Data vault:使用 hubs、links 和 satellites 存储 data。
  • Dimensional:使用 facts 和 dimensions 存储 data。
  • One big table:Denormalized data,所有 values 都存储在一张 table 中。
  • Relational:Data 以 normalized state 存储。
  • Common data models:在特定 industries 中使用的 open source 和 community-supported data models。

还有其他方法存在,并且一些 architects、data modelers 和 vendors 会使用这些 techniques 的自己版本或组合。最终,你需要决定什么最适合自己的 business case。无论你做什么决定都可以,只要确保有一个你觉得靠谱的 plan。

作为作者,我们职业生涯中大量时间都在构建 dimensional models,因此本书内容和示例会偏向这种方式。这并不意味着这是你使用 dbt 的唯一方式,甚至不意味着它是最佳方式。我们对它有偏好,但也承认许多 teams 使用其他 approaches 也非常成功。如何 model data 完全取决于你,我们只是建议在开始时认真思考这一点。许多公司忽视了这一步,现在正在花大价钱请 consulting companies 来修复它。

The Skills Needed to Use dbt

在开始使用 dbt 之前,理解使用它所涉及的 skills 非常重要。对于任何新工具,我们都会先看这一点,以判断现有 skill sets 能多好地迁移到该工具上,并且我们总是欣赏那些清楚列出并解释这些内容的材料,而不是让 user 自己去猜。

dbt 只是一个供你在其中工作的 framework,你仍然需要其他 skills 才能成功使用它。虽然 dbt 本身也是一项 skill,但还有其他方面共同构成了 Analytics Engineer 所需技能版图。好消息是,如果你以前处理过 data,那么它并不是一个难学或难适应的工具。与市场上其他工具相比,我们认为它是最容易学习的工具之一。

以下是开始使用 dbt 之前,有一些背景会很有帮助的核心技术技能。虽然它们的重要性并不相同,而且其中许多可以在 dbt 旅程中边做边学:

  • SQL(primary skill)
  • Jinja(Python developers 使用的 templating language)
  • YAML(configuration 和 property files)
  • Python(取决于 use case)
  • Data modeling
  • Source control

在接下来的 sections 中,我们会逐一回顾每项 skill,以及它在 dbt 中扮演的角色,并给出一个 experience score,帮助你了解 prior experience 有多重要。评分范围是 1 到 5,1 表示我们认为你不需要任何 prior experience,5 表示你应该非常有经验。

Skill #1:SQL

有效使用 dbt 所需的主要技能是编写 SQL(structured query language)。dbt 只要求你能够编写简单的 SELECT statements,而这是任何人学习 SQL 时最先学习的内容之一。只要你能写这些 statements,就可以开始使用 dbt。不过,如果你拥有 advanced SQL coding skills,就会成为更有效的 dbt developer。简单 SELECT statements 可以完成一些事情,但在后续旅程中,你很可能需要用 complex queries 做更多事情。例如,我们建议你熟悉 CTEs 和 window functions,以提升 SQL 技能。SQL 是这个列表中我们认为你必须熟悉的一项技能。如果你不熟悉,那么在继续 dbt 旅程之前,可能需要后退一步,先学习并熟悉 SQL。本书不会教你如何编写 SQL,我们建议你利用大量其他关于这个主题的资源。

Note

在开始 dbt 旅程之前,能够舒适地编写 SQL SELECT statements 是你需要具备的主要技术前提。我们认为其他技能要么容易培养,要么对大多数 use cases 来说并不是完全必要。

Experience Score:4/5

dbt 并不要求你拥有 advanced SQL knowledge 才能使用,但它确实要求你能够舒服地编写 SQL。如果你已有 foundational knowledge,可以在这里提升技能;不过,如果 SQL 对你来说完全是新东西,而你又有其他技能,我们建议你先考虑其他更适合那些技能的工具。

Skill #2:Jinja

下一项重要技能是 Jinja。Jinja 是 Python 中使用的一种 web templating language,它打开了很多可能性,能完成用 SQL logic 做起来很复杂,或需要写 functions 才能完成的事。除非你以前使用过 Python,否则这可能是全新的内容。不过别担心,它并没有听起来那么可怕,而且可以很容易地和 dbt 一起学习。你需要知道几个核心 Jinja commands,其他内容可以在开始使用产品后逐步提升。

dbt 很好地服务于 SQL developers,我们知道这项技能对希望使用 dbt 的人来说可能是新的,所以我们专门在第 6 章深入探索 Jinja。要充分发挥 dbt 的价值,你确实需要学习它,但即便只有限使用 Jinja,也可以拥有非常成功的项目。

Experience Score:2/5

有 Jinja 或 Python 经验会很有帮助,但并不是必要条件。基础内容非常简单,不过更 advanced use cases 可能会有一点 learning curve。

Skill #3:YAML

具备 YAML 的基础理解,是开始使用 dbt 的好技能,因为 dbt 会使用 YAML 定义 project 的 configurations 和 properties。不过,有一些 YAML 经验当然有帮助,但我们并不认为它是必须的 prerequisite。YAML 的一个优势是,它非常 human readable 且易于学习,所以即使从未使用过,也不难掌握。我们会在本章稍后介绍 YAML basics,本书也会为你提供开始使用 YAML 的扎实基础。你会发现,在 dbt 中,你对 YAML 所做的许多修改都是 repetitive 的,所以一旦找到节奏,就没问题。

Experience Score:2/5

拥有 YAML 经验肯定有帮助,但我们认为它足够简单,任何人即使没有 prior experience,也能快速掌握。

Skill #4:Python

dbt 主要是一个 SQL-first tool,不过它也支持运行 Python。我们并不认为 Python 是使用 dbt 的必要条件,它更像 nice-to-have,并且可能只有一部分 users 会使用。截至本文写作时,Python support 仍然较新,因此它未来可能成为 dbt ecosystem 中更重要的部分。不过,既然这个 feature 已经可用,并且可能适合某些 use cases,我们想在这里提一下。能够运行 Python 的优势是,它可以用于编写 custom scripts 和 plug-ins,扩展 SQL 功能之外的能力,并且可以用更少代码完成一些 operations。dbt Labs team 明确表示,这并不是为了替代 SQL,而是作为一种选项,用来填补 SQL 无法覆盖的 gaps。

本书不会教你 Python,但会在第 4 章深入介绍如何使用 dbt 构建 Python models,以及什么时候可能考虑在 dbt 中使用 Python。你在这里经验的价值,很大程度取决于你是否打算使用 Python models。知道 Python 对使用 dbt 不是必要条件,但确实有帮助。

Experience Score:1/5

对大多数人来说是 1/5,但如果你知道自己需要使用 Python,这个分数会更高。

Skill #5:Data Modeling

知道如何 model data 并有一个 plan,是一项重要技能。这是我们在本章前面提到过的内容,也是我们认为很多 dbt users 会忽视的内容。我们不想重复前面所说的一切,但在开始使用 dbt 之前,你应该对 data modeling 的不同方式有基本理解,并且有一个 plan。理解不同 models 的 pros / cons,对帮助你围绕 model builds 制定 strategy 很重要。

在许多公司中,可能有 architects 或 senior engineers 创建 model,然后交给 team,这会降低经验门槛。我们认为所有 team members 对自己正在使用的 model type 有基本理解会很有帮助,但如果团队中有其他有能力的人,这并不是入门障碍。

Experience Score:1/5

如果 team 中有其他 capable members,是 1/5;如果你是负责 leading design 和 implementation 的人,是 4/5。

Skill #6:Source Control

在使用 dbt 之前理解 source control basics 很重要,因为 dbt 被设计为用于 collaborative environment,并依赖 source control 管理和跟踪 data transformation code 的 changes。Source control 是一种跟踪和管理 files,例如 code 或 documentation 变化的方式。它在 software development 的大多数领域中使用,使多个 developers 能够同时处理同一个 project,同时确保 changes 被正确跟踪和协调。常见工具包括 GitHub、GitLab、Bitbucket 等。

在 dbt 中,source control 用于跟踪和管理 dbt project 中的 changes,包括 models、seed data、snapshots 和 test files。通过使用 source control,你可以确保 dbt project 被 versioned,这意味着你可以按需 track 和 roll back changes。当团队协作时,这一点尤其重要,因为它使你能够轻松协调 changes,并避免或解决 conflicts。作为本书作者,我们认为至少对这个流程有一些 familiarity 是很有价值的。如果没有也没关系,因为 dbt 让设置和使用变得很简单。如果你使用 dbt Cloud,那么在开始之前就必须设置 repo 并连接它。

Experience Score:2/5

你应该对 source control 如何工作有基本理解。任何相关经验都会迁移到这里。

The Benefits of dbt

Data market 中充斥着可以用来管理 data 和构建 pipelines 的工具,那么 dbt 有什么特别之处?与其他工具相比,使用 dbt 执行 data transformation tasks 有几个好处。下面列出了一些好处,其中许多在本章前面已经提到过:

  1. dbt 专门为 data transformation 和 analytics 设计,并提供许多针对这些任务优化的 features。例如,dbt 提供 dependency management、incremental model builds 和 data testing,可以帮助你优化 data transformation processes 的 performance。
  2. dbt 是由 SQL users 为 SQL users 构建的,而 SQL 是一种广泛使用且广为人知的数据操作和分析语言。这使 Analysts 和 Data Engineers 即使不熟悉其他 programming languages,也能轻松学习和使用 dbt。
  3. dbt 是 open source,并且拥有强大的 users 和 developers community,这使你在使用该工具时容易找到帮助和资源。在我们看来,dbt Slack channel 是 tech community 中最好的 Slack 社群之一。
  4. dbt 被设计为用于 collaborative environment,并提供 version control、documentation 和 testing 等 features,帮助你与团队中的其他 analysts 和 data engineers 有效协作。
  5. dbt 很 flexible,可以与广泛 data sources 和 target databases 一起使用。这使它非常适合那些需要集成多个 sources 和 systems 数据的组织。

总体而言,dbt 是用于 data transformation 和 analytics 的强大且有效的工具,非常适合需要定期执行这些任务的组织。许多决定采用 dbt 的 users,都是因为上述一个或多个好处。我们知道整本书都会覆盖这些内容,但这里想集中强调一下,让它们更容易阅读。

Connecting to Your Database

如前所述,dbt 没有 compute engine,而是依赖你连接到的 warehouse 或 data store 的 compute。如果没有为 dbt 配置 target,就无法运行任何内容。dbt 可以被配置为指向多种 SQL-speaking databases、warehouses、data lakes、query engines 和 analytical platforms。不过,根据连接类型不同,它们的 support levels 也不同。每个 connection 属于四类之一:dbt Labs supported、vendor supported、community supported 和 yet to be built。图 1-3 展示了当前 supported connectors 的可视化。注意,当你阅读本书时,该列表很可能已经不同,因此请查看官方 dbt docs 以获取最新信息。

image.png

图 1-3:dbt supported connectors 视图

第一类是 dbt Labs supported。这些 adapters 由 dbt Labs 维护和支持,也是目前 dbt Cloud 支持的唯一 adapters。当前 connectors 列表包括 PostgreSQL、Redshift、Snowflake、BigQuery、Apache Spark、Starburst 和 Trino,不过我们完全预期这个列表会继续增长。如果你计划使用 dbt Cloud,但没有看到自己平台被列为 official supported,建议查看 dbt Labs 的最新 documentation,看看它是否已经支持,或联系 dbt Labs support,了解该平台是否计划很快发布。

下一类 adapters 是 vendor supported。这意味着这些 adapters 由 product vendors 构建和维护,并由 vendor 提供支持。它们通常是稳定 connectors,并且已经拥有相当规模的 user base。要使用这些 adapters 中的大多数,你需要使用 dbt Core。今天,这个列表包括 ClickHouse、Databricks、Cloudera Impala、Firebolt、Oracle、Trino、MindsDB、SingleStore、TiDB、Rockset、Starburst、Teradata 等平台。

第三类是 community-supported adapters。这些 adapters 是 community 中个人或团队创建并共享的。一些 adapter 可能比其他 adapter 工作得更好,我们强烈建议在考虑用它们构建 production workloads 之前先进行测试。由于这些 adapters 是 community supported,如果遇到问题,你也可以提交 pull request,帮助修复 adapter 中的问题。确实有人在 production environments 中使用这些 adapters,但我们建议谨慎,因为其中一些可能变得 out of date,或不总是足够 stable。随着 community-supported adapters 改进,它们可以通过 dbt 的严格 validation process 获得 verified。被 dbt verified 的 adapters 本质上获得了 dbt 的认可,表明它们已经 production ready。这些 adapters 大多数会由 vendors 创建和维护,但不一定必须如此。如果你发现缺少某个 adapter,并希望构建一个并让它被 verified,建议查看官方 dbt docs 了解这个 process。

最后一类是 yet to be built。通过 adapter plug-in,dbt 可以扩展到任何 SQL-speaking database、warehouse、data lake、query engine 或 analytical platform。如果你有兴趣构建自己的 adapter,dbt 提供了相关说明。这超出了本书范围,如果你想探索这条路径,建议查看官方 dbt documentation 获取更多信息。

dbt Cloud vs. dbt Core

你可以通过多种方式使用 dbt。一种是使用免费 open source 版本,名为 dbt Core;另一种是使用 enterprise product,名为 dbt Cloud。

dbt Core 是 dbt 的免费 open source version,可以安装并运行在你自己的 computer 或 server 上。它被设计为可以与广泛 data sources 和 target databases 一起使用,并提供多项针对 data transformation 和 analytics 优化的 features。需要注意的是,dbt Core 本身没有直接关联的任何 compute resource,因此你需要利用其他 service 来 schedule 和 execute dbt jobs。我们会在第 2 章介绍 dbt Core setup;不过,图 1-4 展示了一个 dbt Core project 在流行 VS Code IDE 中的样子。

image.png

图 1-4:使用 dbt Core 的 project setup 视图

dbt Cloud 是 dbt 的付费 cloud-based version,由 dbt team 托管和管理。它提供许多与 dbt Core 相同的 features,但附加了多个简化使用的 components,包括:

  • Browser-based IDE(hosted compute)
  • Job scheduling(hosted compute)
  • Logging and alerting
  • GitHub and GitLab integration
  • Hosted documentation
  • Only dbt Labs–supported adapters

图 1-5 展示了 dbt Cloud interface 的样子。

image.png

图 1-5:使用 dbt Cloud 的 project setup 视图

dbt Core 和 dbt Cloud 的一个关键区别在于它们的 deployed 和 used 方式。dbt Core 安装并运行在本地,而 dbt Cloud 通过 web interface 访问和使用。不过,dbt Cloud 正在开发一些新功能,使 dbt Cloud users 能够使用自己的 IDE,例如 VS Code。不过,dbt Cloud 更容易设置和使用,但在与其他 tools 或 systems 集成方面可能不如 dbt Core 灵活。话虽如此,dbt Labs 正在不断发布新 features,以进一步支持 dbt Cloud 与 third-party tools 的集成。dbt Core 和 dbt Cloud 的另一个区别是 pricing model。dbt Core 是 open source 且免费使用,而 dbt Cloud 是付费服务,目前基于访问服务的 users 数量定价。虽然我们始终预期会有免费 open source 版本,但 dbt Cloud 的定价方式始终可能变化。此外,预计未来 feature gap 会继续扩大,因为 dbt 会尝试推动更多人使用 cloud product。

决定使用哪种方式,是你需要尽早做出的选择。在下一章中,我们会回顾如何 setup project,并比较这两个不同 offerings,同时为 decision-making process 提供更多 context。

Project Structure

第一次构建 dbt project 时,dbt 会根据其推荐使用方式创建默认 folder structure。创建出的每个 folder 和 file 都有特定目的。你可以通过编辑 dbt_project.yml file,按自己喜欢的方式重塑 folder structure,但我们通常不建议这样做,尤其是对于 beginner users。现有 documentation 都围绕这个 folder structure 展开,如果你修改它,未来寻求帮助时可能会遇到困难。

默认 project build 会创建以下 folders。每个 folder 都代表 dbt 的不同功能,我们会在后续 sections 中覆盖它们:

  • analyses
  • dbt_packages
  • logs
  • macros
  • models
  • seeds
  • snapshots
  • target
  • tests

图 1-6 展示了 dbt Cloud 中 project 的样子;如果你通过自己喜欢的 IDE,例如 VS Code,使用 dbt Core,视图也会非常类似。

image.png

图 1-6:默认 dbt project folder structure 视图

本书的安排方式是,每一章都会聚焦这些 folders 的用途,不过这里先介绍它们,让你对 big picture 有一个概念。接下来几个 sections 会概览每个 directory folder 及其 general purpose。我们会按字母顺序介绍,而不一定是你在 project 中构建 models 的顺序。虽然可以修改这些 folders 的名称和结构,但本书中不会这样做。

Directory #1:Analyses

Analyses folder 是一个用于存储需要被保存、但不一定是 data model 一部分的内容的地方。dbt 会 compile 存储在该 directory 中的一切内容,但它不会在 run 或 build 中执行。我们将其更多视为一个 sandbox area,Analysts 可以在这里 archive、create 和 share core model 之外使用的 queries,同时仍然利用 source control 和 referencing other models。由于这个 directory 主要作为 sandbox 使用,本书后面不会进一步覆盖它,但我们希望你知道它是可用的。

Directory #2:dbt_packages

作为每个 dbt project 的一部分,你会有一个 packages.yml file,用于将其他 open source 和 community-built projects 包含到自己的 project 中。这些 packages 对你非常有益,因为你可以利用其他 developers 的工作,而不必自己构建。可以把它类比为在 Python environment 中使用 pip 安装和使用 packages。有些 packages 包含 macros,也就是 functions,用于简化可能需要复杂 SQL 的 transformations;也有些 packages 是为特定 datasets 构建的,会替你 model data。我们强烈建议你熟悉已有 packages,并且会在本书中推荐几个我们认为 must-have 的 packages。你可以在 GitHub、dbt Slack community 中查看它们,也可以访问 hub.getdbt.com/ 查看 dbt Labs 认可的列表。

dbt_packages folder 是这些 packages 在 project 中 materialize 的位置。你需要在 packages.yml file 中添加一个 entry 来包含 package,然后使用 dbt deps command 将其 materialize。完成后,使用该 package 构建的 models 就可以在你的 project 中使用。我们会在第 6 章介绍如何设置 packages,但整本书中会提到一些你可能想考虑使用的重要 packages。

Directory #3:Logs

你大概能猜到,logs folder 是 dbt project 中用于存储 log files 的 directory。Log files 包含 dbt runs 的 progress 和 results 信息,包括生成的任何 errors 或 warning messages,在 troubleshooting failures 时很有帮助。大多数情况下,如果你使用 dbt Cloud,会使用 integrated development environment(IDE)生成的 output results,但它们也会被写入该 directory。

本书不会为这个目录专门安排一章,但在讨论其他主题时会提到这个位置。我们认为新 users 了解它很重要,因为它对 troubleshooting issues 很关键。

Directory #4:Macros

Macros 是可以在 project 中多次复用的代码片段。它们类似于其他 programming languages 中的 functions,并使用 Jinja 编写。事实上,你最常使用 Jinja 的地方很可能就是这里。这也是为什么我们将 Jinja 和 macros 合并到同一章中,也就是第 6 章来介绍。

Directory #5:Models

Models folder 是 dbt project 中 data transformations 的主要位置,也会是你花费最多时间的地方。在这个 folder 中,你会创建单个 files,这些 files 包含将 raw data transform 为最终 data state 过程中的 logic。你通常会在这个 folder 内拥有几个 subdirectories,它们可能包含 transformation process 的不同部分,例如 staging、marts 和 intermediate。制定一个良好的组织策略,会对你的 dbt 旅程有帮助。我们会在下一章讨论 project setup 时分享推荐的 design structure。第 4 章也会更深入地讨论这个主题。

Directory #6:Seeds

Seed folder 是 dbt project 中包含 seed data 的 directory。Seed data 是在 dbt 运行任何 models 之前,可以 load 到 target database 中的数据。这类 data 通常用于填充 lookup tables,或为 analytics 提供 reference data。它只应该用于 small sets of static data,这些 data 可能不存在于 source database 的 table 中,但仍需要被引用。例如,你可能有一个 CSV file,其中包含 countries 及其 country code 的列表,需要在 models 中引用。这个列表很小,也不太可能频繁变化,因此可以将其存储在 seed file 中,而不是 source database 中。Seeds 会在本书第 3 章中更详细介绍。

Directory #7:Snapshots

Snapshot folder 是 dbt project 中用于存储 snapshots 的 directory。由于其独特性,它是唯一被拆分到自己 folder 中的 dbt transformation 类型。Snapshot data 是 source database 中 data 在某个 specific point in time 的副本。Snapshots 是 dbt 的一项 feature,用于跟踪 data 随时间发生的变化,并确保 models 基于 accurate 和 up-to-date data。Snapshots 与 Type-2 slowly changing dimension 非常接近,其中有 valid_fromvalid_to dates。这使你能够保留 records 的历史,并捕获 point-in-time data values。Snapshots 会在本书第 5 章中更深入覆盖。

Directory #8:Target

Target folder 有几个用途,但主要两个是存储 metadata files 和 compiled SQL。几乎每次在 dbt 中执行 command,它都会生成并保存一个或多个 artifacts,这些也包含在 target directory 中。其中一些是 JSON files,例如 manifest.jsoncatalog.jsonrun_results.json,用途很多,包括生成 documentation、执行 state comparisons、change tracking、project monitoring 等等。虽然本书没有专门章节介绍 target directory,但会在整本书中引用这些生成的 JSON files,并更详细描述它们如何使用。

首先,target directory 存储一组 .json files,包含 dbt project 的 metadata。第一个需要知道的 file 是 manifest.json,它包含大量关于 dbt assets 的 metadata,包括 configs、node relationships 和 documentation blocks。你永远不需要直接编辑这个 file,因为它由 dbt 自动生成和维护,但当你探索这个 file 时,很快会意识到其中包含极其宝贵的 metadata。你可以直接与这个 file 交互,用于创建 logs、test coverage reports 等。在幕后,dbt 会使用这个 file 来帮助生成 documentation site,以及进行 state comparison。接下来是 run_results.json file,正如你可能猜到的,它包含 dbt project 某次 invocation results 的 metadata。使用这个 file 在 database 中创建 logs 非常常见,这样你就可以长期监控 job results。幸运的是,有一些 packages 可以替你完成繁重工作,我们会在本书后面讨论。最后生成的两个 files,catalog.jsonindex.html,仅用于生成 documentation site。你不需要直接与它们交互,但它们需要存在于 project directory 中,documentation site 才能正确工作。

除了这些由 dbt 生成的 artifact files,这里还有两个 subdirectories。第一个是 compiled folder,用于存储 .sql files,表示 model files 的 compiled SQL。实际上,compiled SQL 就是移除 Jinja 并替换为 raw SQL 后的 model file。不过,此时 compiled SQL 仍然只是 SELECT statements 的表示,还没有包含 DDL 或 DML。接下来是 run folder,它存储发送到 data platform 的 queries。你会在这些 files 中看到包含所有 boilerplate DDL 和 DML 的 SQL,这些内容用于在 database 中构建 objects。同样,除非进行严肃 debugging,否则你并不需要经常直接与它们交互。

需要注意的是,target folder 不用于存储 seed data 或 snapshot data。Seed data 会在 models 构建前 load 到 target database 中;snapshot data 则被 dbt 用作 reference,用于跟踪 source data 的变化。Target folder 专门用于存储 model builds 的结果,以及 compiled SQL。

Directory #9:Tests

Tests folder 是 dbt project 中用于存储 test files 的 directory。Test files 包含 SQL queries,用于测试 model results 的 accuracy 和 integrity。dbt 有几个 product 原生的 common tests,只需要在 YAML files 中引用即可;不过,你也可以构建 custom tests 来支持自己的 specific business case。我们会在第 8 章更深入讨论 tests。在那里,我们会介绍 built-in tests、你可以在该 directory 中构建的 custom tests,以及 open source dbt packages 中包含的 tests。

Supported File Extensions

前一节中,我们覆盖了 dbt 默认创建的 directories,但这只是开始。要使用 dbt,你需要在这些 folders 的上下文中创建包含 programming text 的 files。dbt 支持很多不同 file types,但以下是最常用的,也是本书中会展示示例的类型:

  1. .sql:这是 dbt 最常用的 file extension,用于存储 SQL scripts。
  2. .yml / .yaml:该 file extension 用于以 YAML format 存储 configuration files。dbt 使用这些 files 定义 data model 的 structure,以及需要应用的 dependencies 或 transformations。
  3. .csv:该 file extension 用于以 comma-separated values(CSV)format 存储 data。dbt 可以将 CSV files 作为 data models 的 seed data。
  4. .py:该 file extension 用于存储 Python scripts。dbt 允许你编写 custom Python code,以执行 advanced data transformations,或以其他方式扩展 dbt functionality。
  5. .md:该 file extension 用于存储 Markdown files。你可以在 dbt repository 中包含 documentation,而 Markdown 是通过 doc blocks 编写 reusable documentation 的常用格式。

这些代表了你今天可以在 dbt project 中包含的 file types,但未来它也可能支持运行其他 file types 和 extensions。你可以通过编写 custom code 或使用 third-party libraries 来扩展 dbt Core functionality。这可以允许你使用 dbt out of the box 不支持的 additional file types 或 extensions。不过,这需要大量额外 setup 和 configuration,而且你需要编写 custom code 将新的 file type 或 extension 与 dbt 集成。如果你感兴趣的 file type extension 不在前面列表中,建议查看官方 dbt documentation 看是否支持。如果不支持,community 可能已经创建了一些可用 solutions。对于普通 user 来说,只创建 .sql.yml files 通常就足够了。

Types of Models

在 dbt 中构建 models 是你会花最多时间的地方。Models 是定义为 .sql files 的 SELECT statements,或定义为 Python models,用于执行 data transformations。这些就是让 project 活起来的 items。在 dbt 中,你有四种不同方式来 materialize model。我们会在第 4 章更详细覆盖这个内容,但由于它对于 foundationally understanding dbt 非常重要,所以这里先做 high-level 介绍。四种类型如下:

  • Table
  • View
  • Ephemeral
  • Incremental

如果你以前使用过 databases,那么前两项应该非常熟悉。Tables 是 database objects,其中 data 会写入 disk,并形成一个新的 self-contained object。View 是 database object,存储一个 query,每次执行 view 时都会运行该 query。View 不会移动或写入 data,因此你写的 code 每次 view 执行时都必须被执行。Views 也是 dbt 中的 default materialization。如果使用这两种 materializations 中任意一种,那么每次 invoke dbt 时,object 都会从头重建。对于 views,这通常没问题;但对于 tables,这意味着你的所有 data 也必须重新 load。在第 4 章中,我们会提供大量关于何时使用哪种方式的 guidance。

下一种类型是 ephemeral model。Ephemeral models 本质上就是 SQL 中的 CTEs(common table expressions)。它们不会存在于 database 中,只能在 dbt 内部被引用。我们建议在 project 中非常谨慎地使用它们。

Pro Tip

你需要非常熟悉编写 CTEs,因为在 dbt 中会大量使用它们。由于你只能编写 SELECT statements,不能使用 temp tables 或 table variables。

下一种类型是 incremental model。Incremental models 会 materialize as table;不过,它们被配置为允许 dbt 自上一次运行以来 insert 或 update records。当处理大量数据并且不希望每次都 reload 时,这非常有用。你仍然只能编写 SELECT statements;不过,dbt 会将它 compile 成需要运行的 commands。在其他系统中,你需要自己编写 UPSERT 或 MERGE logic,但 dbt 会让它变得简单。与 tables 相比,使用 incremental models 稍微复杂一些,但在处理 bigger data 时,你肯定会用到。dbt 官方建议先从 table materializations 开始,当 performance 需要时再迁移到 incremental models,我们也同意。尽可能保持简单,并在需要时演进。

Snapshots

Snapshots 在 dbt 中算是独立的一类,但在某些方面与刚才介绍的 materializations 类似。Snapshots 会 materialize as table,并在需要长期跟踪 history 时使用。其本质上实现了 Type-2 slowly changing dimension(SCD)。这意味着当 source 与 target 之间检测到变化时,target 中会创建一条 new row,而不是直接覆盖 existing value。正如本章前面 project structure overview 中所见,snapshots 单独存在,因为它们具有一些独特特性。和 incremental models 一样,如果你是 dbt 新手,我们不建议一开始就使用 snapshots,只有当 needs dictate it 时才开始使用。第 5 章会专门详细介绍这个概念。

Executing dbt Commands

在 dbt 中构建 models 是使用 dbt 的第一步,但你仍然需要一种方式来执行这些 models。dbt 有自己的一组 commands,可以通过 command line 执行不同 tasks,包括 building models、running tests 和 generating documentation。接下来几节中,我们会回顾当前支持的所有 dbt commands。我们会根据 commands 是否同时支持 dbt Cloud 和 dbt Core,或是否只支持 dbt Core,对它们进行拆分。目前没有只支持 dbt Cloud 的 commands。

Supported by Both

以下是 dbt Cloud 和 dbt Core 都支持的 commands:

dbt run

用于运行 specific model 或一组 models。当你只想 build 和 deploy dbt project 中特定 models,而不是所有 models 时,它很有用。

dbt build

用于 build 和 deploy data transformation models。运行 build command 时,dbt 会执行 models 中的 SQL code,并将结果 load 到 target database 中。该 command 会用单个 command 运行 models、tests、snapshots 和 seeds。

dbt deps

用于拉取 packages.yml file 中指定版本的 packages。

dbt test

用于在 models 和 data 上运行 tests,确保它们 accurate 和 reliable。Tests 被定义在 dbt project 中 test folder 下的 SQL files 中。运行 test command 时,dbt 会执行 tests 并报告结果。

dbt run-operation

用于运行 macro。

dbt snapshot

用于对 source data 进行 snapshot。Snapshot data 被 dbt 用于跟踪 source data 随时间的变化,并确保 models 基于 accurate 和 up-to-date data。

dbt seed

用于将 seed data load 到 target database 中。Seed data 是一组 reference data,会在 models 构建前 load 到 database 中。它通常用于填充 lookup tables,或为 analytics 提供 reference data。

dbt show

允许你直接从 terminal window preview model、test、analysis 或 SQL query 的 results。

dbt source freshness

用于根据 sources.yml file 中的配置,评估 source tables 是否 stale。

dbt Core Commands

以下是仅 dbt Core 支持的 commands:

dbt clean

用于清理 target folder 和 dbt_project directory。当你想从一个 fresh build 重新开始时很有用。

dbt debug

用于测试 database connection,并返回可用于 debugging 的信息。

dbt init

在使用 dbt Core 时,该 command 用于初始化一个新的 dbt project。

dbt list

用于列出 project 中定义的 resources。

dbt parse

用于 parse 和 validate project 内容。如果存在 syntax errors,该 command 会失败。

dbt docs generate

用于为 dbt project 生成 documentation。它会创建一组 HTML files,其中包含关于 models 的信息,包括它们的 structure、dependencies 和 source data。

dbt docs serve

用于在本地提供 documentation,并用默认 browser 打开 documentation site。

dbt Command Flags

前一节提供了用于执行 dbt project 各方面内容的 base commands,而每个 command 都有一些 additional flags。在 dbt 中,flags 是 command-line arguments,你可以用它们修改 dbt commands 的行为。虽然我们不会在这里探索每个 command 的所有可能 flags,但想给你一个概念,了解可以做什么。你最常使用的 commands 之一是 dbt build。你可以只运行 dbt build,它会运行所有 transformations、tests 和 seeds;但如果你想限制 scope,只运行部分 transformations 呢?在这种情况下,就需要包含 flags 来告诉 dbt。以下是 dbt build command 相关的一些 flags:

--select

用于只运行 specific transformation models,需要在该 option 后跟 model 名称。这是一个非常强大的 flag,允许你基于 package name、model names、directory、path、tags、configs、test types 和 test names 进行 filter。

--exclude

用于指定一组应从 build 中排除的 models。它可以与 --select flag 结合使用,从而 build 除指定 models 之外的所有 models。它允许与 --select flag 相同的 filters。

--resource-type

该 flag 允许你选择要运行的 resource type。

--defer

该 flag 允许你在 project 中运行 models 或 tests,并跳过 upstream dependencies。当你想在大型 project 中测试少量 models,并且不想花时间和 compute 运行所有内容时,它很有用。

--selector

你可以在 YAML 中编写 resource selectors,将其保存到 project 中,并在 command 中使用该 flag 引用它们。

除了这些 flags,还有一些非特定于 resource builds 的 additional flags:

--help

显示所有可用 commands 和 arguments。当你不记得所有 options 时很有帮助。

--vars

用于向 project 提供 variables。

--full-refresh

用于强制对 incremental models 做 full refresh。它会 drop existing tables 并重新创建它们。

--fail-fast

使 dbt 在单个 resource build failed 时立即退出。

--threads

用于指定 dbt build models 时应使用的 threads 数量。它可以通过 parallelizing models execution 来优化 build process 的 performance。

--target

用于指定 database 的 target connection。该 flag 仅用于 dbt Core deployments。

这些只是为了让你了解 dbt-specific commands 能做什么。每个 command 也可能拥有自己独特的 options,因此你需要查看官方 documentation 来了解所有可能性。在本书中,我们会经常引用这些 commands,并可能使用一些最常见 options;不过,我们无法覆盖所有可能场景。

Case Sensitivity

使用 dbt 时,case sensitivity 方面有一些复杂性:有些 elements 是 case sensitive,有些不是,有些可能取决于 target data stores 的 case sensitivity。作为本书作者,我们处理过许多 database systems,知道这会非常令人沮丧,尤其是当你长期使用 case-insensitive systems 时,所以这里特别说明一下。

一般来说,dbt 本身在 compile SQL scripts、configuration files 或其他 types of files 时是 case sensitive 的。例如,以下 SQL statements 并不等价,并且会被 dbt 视为不同内容:

SELECT * FROM {{ ref('customers') }};
SELECT * FROM {{ ref('Customers') }};
SELECT * FROM {{ ref('cUsToMeRs') }};

不过,当 underlying data store 是 case sensitive 时,就可能出现问题。一些 databases,例如 PostgreSQL,默认就是 case sensitive,这意味着它们会区别对待 uppercase 和 lowercase characters。在这些情况下,dbt 会尊重 underlying DBMS 的 case sensitivity,因此你需要注意 SQL statements 和其他 files 的大小写。使用前面的示例,在这类系统中可能产生不同结果。因此,在开始使用 dbt 之前,你需要确保了解 data store 的 case sensitivity,以避免后续头疼。

同样值得注意的是,你在 dbt 中所做的大部分事情都是 case sensitive。例如,.yml file extension 通常用于以 YAML format 编写的 configuration files,而 YAML 是 case sensitive 的。这意味着,在编写 YAML configuration files 时,应小心使用正确大小写,因为 dbt 不会自动修正任何 case errors。

从 command line 运行 dbt commands 时,dbt 也是 sensitive 的,就像处理 SQL scripts 和其他 types of files 时一样。这意味着你不能在输入 dbt commands 时使用 uppercase、lowercase 或二者组合。作为规则,所有 dbt execution commands 都应该小写。让我们看 dbt run command 的正确和错误大小写。错误的写法会让 dbt 报错,而不是运行:

dbt run - Correct
dbt Run - Incorrect
dbt rUn - Incorrect

dbt flags 接受的 arguments 也是 case sensitive 的。例如,--select flag 可用于运行 selected models,它是 case sensitive 的。这意味着在指定要运行的 model 时,需要使用正确大小写,因为 dbt 不会自动修正 case errors。假设我们的 dbt project 中有一个名为 Customers 的 model。如果运行以下 command,dbt 会完成该 model 的 transformation:

dbt run --select Customers

不过,如果大小写与 model name 不完全匹配,dbt 会失败,并声明找不到它,只有当你输入正确大小写后才会运行。

Pro Tip

处理 dbt 中的 case sensitivity 可能很麻烦,因此我们建议假设你做的所有事情都需要 case sensitive,而不是试图分别记住哪些需要、哪些不需要。

What Is YAML?

YAML 在你的 dbt 旅程中扮演重要角色,因此理解它很关键。如前所述,YAML 是一种 human-readable data serialization language,最常用于 configuration files。这个 acronym 的含义取决于你问谁,它可以表示 YAML Ain’t Markup Language,也可以表示 Yet Another Markup Language。它的 object serialization 使其成为替代 JSON 或 XML 部分复杂性的可行方案。

今天,许多现代工具都依赖 YAML 作为其 framework 的一部分。让我们看看使用 YAML 的一些好处:

  • Human readable
  • Unambiguous
  • Portable across most programming languages
  • Friendly to version control
  • Strict syntax requirements,因此所有内容都以类似方式编写
  • Simple and clean syntax
  • Quick to implement
  • Secure implementation,可以关闭其他 languages 中发现的 exploits
  • Easy to learn

在 dbt 中,YAML files 同时用于 properties 和 configurations。Properties 通常声明 project resources 的相关信息,例如 descriptions、tests 和 sources。Configuration files 则告诉 dbt 如何在 warehouse 中 build resources,并包含 materializations、object locations 和 tags 等内容。这些都会在本书中覆盖,所以如果你现在不确定它们是什么意思,也没关系。这里的关键点是理解 YAML files 用于定义 properties 和 configuration。

如果你是 YAML files 新手,了解一些 fundamentals 会很有帮助。本书不是 YAML 教程,但在 dbt 的上下文中开始使用 YAML files 的一个重要概念,是理解 arrays 和 dictionaries 是什么。YAML array 是嵌套在 key 之下的一组相似 values,这个 key 用名称表示。每个 value 都以 hyphen 符号加一个空格开头。让我们看图 1-7 中的 YAML file 示例,理解它如何工作。

image.png

图 1-7:YAML file 中的 array 示例

下一个 component 是 dictionary。Dictionaries 是用于映射 key-value pairs 的 mappings。在 YAML 中,dictionaries 可以使用 flow mapping 和 block mapping 两种 syntaxes 表示。在 block mapping dictionary 中,key 和 value pairs 使用 colon syntax 表示。让我们看图 1-8 的示例,看看 connection string 如何用 block mapping dictionary 表示。

image.png

图 1-8:YAML file 中 block mapping dictionary 示例

在 flow mapping dictionary 中,key 和 value pairs 用 comma 分隔,并且整个 pairs 包含在 {} characters 中。因此,使用相同 values,你可以在图 1-9 中看到它们以不同方式显示。在大多数符合 dbt standards 的 YAML files 中,需要使用 block mapping,这样 files 才能正确 parse。

image.png

图 1-9:YAML file 中 flow mapping dictionary 示例

关于 YAML files,我们最后想指出的是,syntax 非常 specific,但这有时既是 blessing,也是 curse。Blessing 在于它非常 strict,因此不会出现每个人都加入自己风格的情况。任何修改 YAML file 的人都必须使用相同 syntax。Curse 在于它如此具体,以至于诸如错误 indentation 这样简单的问题也会导致失败。这是很常见的问题,也是我们刚开始使用 YAML 时会犯的错误。我们认为在使用 dbt 的过程中学习 YAML 足够容易;不过,如果你在 dbt 旅程中发现自己在这方面挣扎,可以查看一些在线 tutorials 和 resources。

The Role of YAML with dbt

上一节中,我们介绍了 YAML 的一些 basics 以及它的一般用途,但它在 dbt 中扮演非常重要的角色。尤其是,它用于定义 dbt project 的 configuration,包括 data sources、target databases、models 和其他 project-specific settings 的 details。

在 dbt project 中,你会创建两类 YAML files。第一类是 configuration type YAML file。这类 YAML file 告诉 dbt 如何 operate。project 中只有一个 configuration type file,也就是 dbt_project.yml。每次 initialize dbt project 时,这个 file 都会自动创建在 dbt project root 下,并且必须始终存在,dbt 才能运行。它与 dbt project 是 one to one 的,你不能创建多个副本。这个 file 告诉 dbt 如何在 warehouse 中 build resources,包括 default folder structures、materializations、object locations 和 tagging 等。如果你想改变 dbt 如何 operate,就需要修改这个 file。下一章会介绍你可能会考虑在这个 file 中设置的 configurations。

第二类被创建的 YAML file 是 property type files。这些 YAML files 通常声明 project resources 的相关内容,例如 descriptions、tests、sources 和 exposures。对于这些 files,你可以有多个,而且通常建议这样做。它们通常位于 model directories 中。这些 files 会在本书多个章节中覆盖,因为它们用于 project 的不同方面。尤其是在第 3、4、8 和 9 章中会讨论它们,因为这些 YAML files 会在那里被使用。

如果你以前没有用过 YAML,也没关系,很快你就会变成专家。你使用它们的方式大量是 repetitive 的,因此一旦掌握节奏,就会很顺手。

The Semantic Layer

当你阅读本书的 chapter list 和 description 时,可能会注意到一个明显缺失的内容:semantic layer。对于不熟悉的人来说,dbt Semantic Layer 于 2022 年 10 月进入 public preview,并迅速引发大量 buzz 和 excitement。其功能是为 data teams 提供一种方式,在 modeling layer 的 upstream 集中定义 business metrics,并向下游流动到 business intelligence、reporting 和 data management tools。这是行业中越来越明显的趋势。然而,在发布时,它存在一些限制,使 data teams 无法真正使用它,最明显的是 join navigation 和有限的 data platform support。

2023 年初,dbt 宣布收购一家名为 Transform 的公司。Transform 由前 Airbnb Engineers 创立,并在很大程度上被认为是 semantic layer 背后的创新者。这是一个重大公告,因为 dbt 需要解决的一些复杂问题,Transform 已经完成。因此,dbt 立即开始尝试整合他们的 semantic layer functionality,这意味着需要重写现有 semantic layer。

虽然我们可以写今天已经存在的内容,但并不认为这有价值。dbt 已经非常明确地表示,它会发生变化,并在 2023 年晚些时候重新发布,而这在本书计划发布之后。等你读到这里时,我们的信息很可能已经过时,所以我们决定直接排除这一部分。如果未来有机会写本书的第二版,这肯定会是我们添加的内容。

Setting the Stage for the Book

在本书其余部分中,我们会深入本章中描述的 specific components。为了帮助你跟上节奏,本书中的大量 sample code 都是一个开放 Apress GitHub repo 的一部分,你可以跟随使用,或自己使用。该 GitHub repo 可以在以下地址找到: github.com/apress/unlo…

我们构建的 project 连接到了 Snowflake instance;不过,你可以连接到任何自己喜欢的 database。代码示例足够简单,应该可以在任何 database 上运行,可能只需要 minor changes。也有少数例外,但我们会在本书推进过程中说明。如果你想用 Snowflake instance 测试,可以在 Snowflake.com 设置 trial account,或者将其指向任何其他 dbt adapter。

最后,我们想说明,本书是为了教你开始成功使用 dbt 所需要知道的内容。我们理解 dbt user community 中有许多不同使用方式,也有很多争议很大的内容。只要去 dbt Slack channel 看一看,你就不可避免会遇到一些争论,尤其是 modeling 话题。本书中的示例和讲解基于我们的偏好和经验,但我们绝不是说这是唯一方式。dbt 是一个极其 flexible 的产品,可以 meet you where you are,并支持你做出的任何决定。此外,dbt 还可以做一些非常 advanced 的事情,而本书大多不会覆盖这些 topics。我们希望本书即使对最没有经验的 dbt users 也足够 accessible,不过也许未来会有一本专门讨论 advanced use cases 的书。

Summary

本章中,我们介绍了 dbt 是什么,以及它在 data analytics 和 warehouses 中扮演的角色。我们了解到,dbt 是一个 open source command-line tool,帮助 Data Analysts 和 Data Engineers 自动化组织 data warehouse 中 transforming、modeling 和 testing data 的过程。它被开发出来,是为了让构建和维护 analytics infrastructure 更容易,尤其是在 data warehousing 和 business intelligence 的 context 中。

借助 dbt,你可以使用 dbt models 编写 SQL 和 Python code,定义 transformations 和 business logic,并将其应用到 data warehouse 中的数据上。你也可以使用 dbt 定义和运行 tests,以确保 data 的 quality 和 consistency。dbt 是一个出色工具,因为它高效、协作友好、可靠,并且融合了许多 software engineering best practices。

本章旨在作为本书其余内容的前置介绍,并创建一个关于后续内容的 overview。如果你感到信息量很大,不用担心,后面我们会花更多时间讨论这里概述的每个 individual component。