dbt项目的数据测试、分析、种子数据及文档实践
立即解锁
发布时间: 2025-08-31 01:03:05 阅读量: 13 订阅数: 12 AIGC 


SQL与dbt数据分析工程
# dbt项目的数据测试、分析、种子数据及文档实践
## 1. 源新鲜度测试
源新鲜度测试是确保数据时效性的重要手段。在检查日志细节时,能看到在数据平台执行的查询,从而进行故障排查。例如,`_etl_loaded_at` 被设置为距离当前时间16小时,若低于这个时间就会发出警告。若想避免警告,可将 `warn_after` 改为更高的值,如17小时,这样所有测试应该就能通过。
源新鲜度测试的目的在于确保数据的时效性,在整体测试体系中十分重要,它能帮助我们及时发现数据质量问题。配置时需根据实际业务需求设置合理的时间阈值。
## 2. dbt测试概述
作为分析工程师,确保数据的准确性和可靠性至关重要,这有助于建立对分析结果的信任,并为组织提供客观的见解。dbt 提供了强大的测试功能,能在数据工作流中快速且轻松地扩展测试,让我们能在问题出现前及时发现。
### 2.1 dbt测试的特点
- **验证性**:dbt 测试主要是对数据的验证,确认数据是否遵循既定模式和结构,类似于软件测试中的验证环节。
- **局限性**:dbt 测试并非万能,它不能测试数据转换逻辑的细节,也不能覆盖所有测试用例,在数据项目中可能需要结合其他测试方法和工具。
### 2.2 dbt测试的分类
dbt 测试主要分为通用测试(Generic tests)和单例测试(Singular tests)两类,下面分别介绍。
#### 2.2.1 通用测试
通用测试是 dbt 中最简单且高度可扩展的测试类型,通常只需编写几行 YAML 代码就能对特定模型或列进行测试。dbt 内置了四种通用测试:
| 测试类型 | 描述 |
| ---- | ---- |
| unique test | 验证特定列中的每个值都是唯一的 |
| not_null test | 验证特定列中的每个值都不为空 |
| accepted_values test | 确保特定列中的每个值都存在于给定的预定义列表中 |
| relationships test | 确保特定列中的每个值都存在于另一个模型的列中,保证引用完整性 |
以下是使用通用测试的示例,我们选择 `stg_jaffle_shop_orders.sql` 模型进行测试:
```yaml
version: 2
models:
- name: stg_jaffle_shop_customers
config:
materialized: view
columns:
- name: customer_id
tests:
- unique
- not_null
- name: stg_jaffle_shop_orders
config:
materialized: view
columns:
- name: order_id
tests:
- unique
- not_null
- name: status
tests:
- accepted_values:
values:
- completed
- shipped
- returned
- placed
- name: customer_id
tests:
- relationships:
to: ref('stg_jaffle_shop_customers')
field: customer_id
```
在命令行中输入 `dbt test` 运行测试。若 `accepted_values` 测试失败,这是预期结果。我们可以通过以下步骤进行调试:
1. 打开日志,展开失败的测试。
2. 点击 “Details”,查看执行的查询。
3. 将查询复制到文本编辑器,只保留内部查询并执行。
通过调试,我们发现 `return_pending` 状态未包含在测试列表中,将其添加后重新运行测试,所有测试应该就能通过。
除了 dbt Core 内置的通用测试,dbt 生态系统中还有更多测试,可通过 dbt 包扩展。此外,还可以自定义通用测试,以满足特定项目需求。
#### 2.2.2 单例测试
单例测试定义在 `tests` 目录下的 `.sql` 文件中,适用于测试特定模型中的特定属性,当 dbt 内置的传统测试无法满足需求时使用。
例如,我们要检查订单的总金额是否为非负数,可在 `tests` 目录下创建 `assert_total_payment_amount_is_positive.sql` 文件,代码如下:
```sql
select
order_id,
sum(total_amount) as total_amount
from {{ ref('int_payment_type_amount_per_order') }}
group by 1
having total_amount < 0
```
可以使用以下命令运行单例测试:
- `dbt test`:执行所有测试。
- `dbt test --select test_type:singular`:仅执行单例测试。
- `dbt test --select int_payment_type_amount_per_order`:执行 `int_payment_type_amount_per_order` 模型的所有测试。
- `dbt test --select assert_total_payment_amount_is_positive`:仅执行我们创建的特定测试。
这些命令提供了灵活的选择,可根据需求选择性地运行测试。
### 2.3 测试源数据
在 dbt 项目中,不仅可以对模型进行测试,还能将测试扩展到源数据。除了源新鲜度测试,还可以对源数据进行通用测试和单例测试。
#### 2.3.1 通用测试源数据
以 `_jaffle_shop_sources.yml` 文件为例,对源数据进行通用测试:
```yaml
version: 2
sources:
- name: jaffle_shop
database: dbt-tutorial
schema: jaffle_shop
tables:
- name: customers
columns:
- name: id
tests:
- unique
- not_null
- name: orders
loaded_at_field: _etl_loaded_at
freshness:
warn_after: {count: 17, period: hour}
error_after: {count: 24, period: hour}
columns:
- name: id
tests:
- unique
- not_null
- name: status
tests:
- accepted_values:
values:
- completed
- shipped
- returned
- placed
- return_pending
```
修改 YAML 文件后,可使用 `dbt test` 或 `dbt test --select source:jaffle_shop` 命令运行测试,所有测试应该能通过。
#### 2.3.2 单例测试源数据
在 `tests` 目录下创建 `assert_source_total_payment_amount_is_positive.sql` 文件,对源数据进行单例测试:
```sql
select
orderid as order_id,
sum(amount) as total_amount
from {{ source('stripe', 'payment') }}
group by 1
having total_amount < 0
```
使用 `dbt test` 或 `dbt test --select source:stripe` 命令运行测试,所有测试应该能通过。
## 3. 分析文件夹的使用
分析文件夹(Analyses)可用于存储临时查询、审计查询、训练查询或重构查询等,帮助我们在不影响模型的情况下检查代码。分析文件是模板化的 SQL 文件,不能在 `dbt run` 期间执行,但可以使用 Jinja 模板,通过 `dbt compile` 查看代码的实际效果,并保持代码的版本控制。
### 3.1 分析文件夹的使用示例
假设我们要分析已完成订单中支付总额最高的前 10 个最有价值的客户,可在 `analyses` 目录下创建 `most_valuable_customers.sql` 文件,代码如下:
```sql
with fct_orders as (
select * from {{ ref('fct_orders')}}
),
dim_customers as (
select * f
```
0
0
复制全文
相关推荐








