当 dbt 遇见 TiDB

dbt (data build tool)是一款流行的开源数据转换工具,能够通过 SQL 实现数据转化,将命令转化为表或者视图,提升数据分析师的工作效率。TiDB 社区在近日推出了 dbt-tidb 插件,实现了 TiDB 和 dbt 的兼容适配。本文将通过一个简单的案例介绍如何通过 dbt 实现 TiDB 中数据的简单分析。

dbt 主要功能在于转换数据库或数据仓库中的数据,在 E(Extract)、L(Load)、T(Transform) 的流程中,仅负责转换(transform)的过程。 通过 dbt-tidb 插件,数据分析师在使用 TiDB 的过程中,能够通过 SQL 直接建立表单并匹配数据,而无需关注创建 table 或 view 的过程,并且可以直观地看到数据的流动;同时能够运用 dbt 的 Jinja 编写 SQL、测试、包管理等功能,大大提升工作效率。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xwT7Kf9P-1649816248320)(/media/when-tidb-meets-dbt/1.png)]

(图片来源:https://blog.getdbt.com/what-exactly-is-dbt/)

接下来,我将以 dbt 官方教程为例,给大家介绍下 TiDB 与 dbt 的结合使用。

本例用到的相关软件及其版本要求:

  • TiDB 5.3 或更高版本
  • dbt 1.0.1 或更高版本
  • dbt-tidb 1.0.0

安装

dbt 除了本地 CLI 工具外,还支持 dbt Cloud (目前,dbt Cloud 只支持 dbt-lab 官方维护的 adapter),其中本地 CLI 工具有多种安装方式。我们这里直接使用 pypi 安装 dbt 和 dbt-tidb 插件。

安装 dbt 和 dbt-tidb,只需要一条命令,因为 dbt 会作为依赖在安装 dbt-tidb 的时候顺便安装。

$ pip install dbt-tidb

dbt 也可自行安装,安装方式参考官方安装教程。

创建项目:jaffle_shop

jaffle_shop 是 dbt-lab 提供的用于演示 dbt 功能的工程项目,你可以直接从 GitHub 上获取它。

$ git clone https://github.com/dbt-labs/jaffle_shop$ cd jaffle_shop

这里展开 jaffle_shop 工程目录下所有文件。

  • dbt_project.yml 是 dbt 项目的配置文件,其中保存着项目名称、数据库配置文件的路径信息等。
  • models 目录下存放该项目的 SQL 模型和 table 约束,注意这部分是数据分析师自行编写的。
  • seed 目录存放 CSV 文件。此类文件可以来源于数据库导出工具,例如TiDB 可以通过 Dumpling 把 table 中的数据导出为 CSV 文件。jaffle_shop 工程中,这些 CSV 文件用来作为待处理的原始数据。

关于它们更加具体的内容,在用到上面的某个文件或目录后,我会再次进行更详细的说明。

ubuntu@ubuntu:~/jaffle_shop$ tree.├── dbt_project.yml├── etc│   ├── dbdiagram_definition.txt│   └── jaffle_shop_erd.png├── LICENSE├── models│   ├── customers.sql│   ├── docs.md│   ├── orders.sql│   ├── overview.md│   ├── schema.yml│   └── staging│       ├── schema.yml│       ├── stg_customers.sql│       ├── stg_orders.sql│       └── stg_payments.sql├── README.md└── seeds├── raw_customers.csv├── raw_orders.csv└── raw_payments.csv

配置项目

  1. 全局配置

dbt 有一个默认的全局配置文件:~/.dbt/profiles.yml,我们首先在用户目录下建立该文件,并配置 TiDB 数据库的连接信息。

 $ vi ~/.dbt/profiles.ymljaffle_shop_tidb:                        # 工程名称target: dev                             # 目标outputs:dev:type: tidb                         # 适配器类型server: 127.0.0.1                  # 地址port: 4000                         # 端口号schema: analytics                  # 数据库名称username: root                     # 用户名password: ""                       # 密码
  1. 项目配置

jaffle_shop 工程目录下,有此项目的配置文件,名为dbt_project.yml。把profile配置项改为jaffle_shop_tidb,即profiles.yml文件中的工程名称。这样此工程在会到 ~/.dbt/profiles.yml文件中查询数据库连接配置。

$ cat dbt_project.yml name: 'jaffle_shop'config-version: 2version: '0.1'profile: 'jaffle_shop_tidb'                   # 注意此处修改model-paths: ["models"]                       # model 路径seed-paths: ["seeds"]                         # seed 路径test-paths: ["tests"]                         analysis-paths: ["analysis"]macro-paths: ["macros"]target-path: "target"clean-targets:- "target"- "dbt_modules"- "logs"require-dbt-version: [">=1.0.0", "<2.0.0"]models:jaffle_shop:materialized: table            # models/ 中的 *.sql 物化为表staging:           materialized: view           # models/staging/ 中的 *.sql 物化为视图
  1. 验证配置

可以通过以下命令,检测数据库和项目配置是否正确。

$ dbt debug06:59:18  Running with dbt=1.0.1dbt version: 1.0.1python version: 3.8.10python path: /usr/bin/python3os info: Linux-5.4.0-97-generic-x86_64-with-glibc2.29Using profiles.yml file at /home/ubuntu/.dbt/profiles.ymlUsing dbt_project.yml file at /home/ubuntu/jaffle_shop/dbt_project.ymlConfiguration:profiles.yml file [OK found and valid]dbt_project.yml file [OK found and valid]Configuration:profiles.yml file [OK found and valid]dbt_project.yml file [OK found and valid]Required dependencies:- git [OK found]Connection:server: 127.0.0.1port: 4000database: Noneschema: analyticsuser: rootConnection test: [OK connection ok]All checks passed!

加载 CSV

加载 CSV 数据,把 CSV 具体化为目标数据库中的表。注意:一般来说,dbt 项目不需要这个步骤,因为你的待处理项目的数据都在数据库中。

$ dbt seed07:03:24  Running with dbt=1.0.107:03:24  Partial parse save file not found. Starting full parse.07:03:25  Found 5 models, 20 tests, 0 snapshots, 0 analyses, 172 macros, 0 operations, 3 seed files, 0 sources, 0 exposures, 0 metrics07:03:2507:03:25  Concurrency: 1 threads (target='dev')07:03:2507:03:25  1 of 3 START seed file analytics.raw_customers.................................. [RUN]07:03:25  1 of 3 OK loaded seed file analytics.raw_customers.............................. [INSERT 100 in 0.19s]07:03:25  2 of 3 START seed file analytics.raw_orders..................................... [RUN]07:03:25  2 of 3 OK loaded seed file analytics.raw_orders................................. [INSERT 99 in 0.14s]07:03:25  3 of 3 START seed file analytics.raw_payments................................... [RUN]07:03:26  3 of 3 OK loaded seed file analytics.raw_payments............................... [INSERT 113 in 0.24s]07:03:2607:03:26  Finished running 3 seeds in 0.71s.07:03:2607:03:26  Completed successfully07:03:2607:03:26  Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3

上述结果中,可以清楚的看到共执行了三个任务,分别加载了 analytics.raw_customersanalytics.raw_ordersanalytics.raw_payments 三张表。

接着,去 TiDB 数据库中看看发生了什么。

发现多出了 analytics 数据库,这是 dbt 为我们创建的工程数据库。

mysql> show databases;+--------------------+| Database           |+--------------------+| INFORMATION_SCHEMA || METRICS_SCHEMA     || PERFORMANCE_SCHEMA || analytics          || mysql              || test               |+--------------------+6 rows in set (0.00 sec)

analytics 数据库中有三张表,分别对应着上述三个任务结果。

mysql> show tables;+---------------------+| Tables_in_analytics |+---------------------+| raw_customers       || raw_orders          || raw_payments        |+---------------------+3 rows in set (0.00 sec)

model 是什么?

在进行下一个步骤之前,我们有必要先了解下 dbt 中的 model 扮演着什么角色?

dbt 中使用 model 来描述一组数据表或视图的结构,其中主要有两类文件:SQL 和 YML。还需要注意到的是:在 jaffle_shop 这个项目中,根据物化配置,models/ 目录下保存的是表结构,而 models/staging/ 目录下保存的是视图结构。

models/orders.sql 为例,它是一句 SQL 查询语句,支持 jinja 语法,接下来的命令中,会根据这条 SQL 创建出 orders 表。

$ cat models/orders.sql{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %}with orders as (select * from {{ ref('stg_orders') }}),payments as (select * from {{ ref('stg_payments') }}),order_payments as (selectorder_id,{% for payment_method in payment_methods -%}sum(case when payment_method = '{{ payment_method }}' then amount else 0 end) as {{ payment_method }}_amount,{% endfor -%}sum(amount) as total_amountfrom paymentsgroup by order_id),final as (selectorders.order_id,orders.customer_id,orders.order_date,orders.status,{% for payment_method in payment_methods -%}order_payments.{{ payment_method }}_amount,{% endfor -%}order_payments.total_amount as amountfrom ordersleft join order_paymentson orders.order_id = order_payments.order_id)select * from final

并且,与这条 SQL 配套的约束信息在 models/schema.yml 文件中。

schema.yml 是当前目录下所有模型的注册表,所有的模型都被组织成一个树形结构,描述了每条字段的说明和属性。其中 tests 条目表示这个字段的一些约束项,可以通过 dbt test 命令来检测,更多信息请查阅官网文档。

cat models/schema.ymlversion: 2...- name: ordersdescription: This table has basic information about orders, as well as some derived facts based on paymentscolumns:- name: order_idtests:- unique- not_nulldescription: This is a unique identifier for an order- name: customer_iddescription: Foreign key to the customers tabletests:- not_null- relationships:to: ref('customers')field: customer_id- name: order_datedescription: Date (UTC) that the order was placed- name: statusdescription: '{{ doc("orders_status") }}'tests:- accepted_values:values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']- name: amountdescription: Total amount (AUD) of the ordertests:- not_null- name: credit_card_amountdescription: Amount of the order (AUD) paid for by credit cardtests:- not_null- name: coupon_amountdescription: Amount of the order (AUD) paid for by coupontests:- not_null- name: bank_transfer_amountdescription: Amount of the order (AUD) paid for by bank transfertests:- not_null- name: gift_card_amountdescription: Amount of the order (AUD) paid for by gift cardtests:- not_null

运行

结果中显示成功创建了三张视图(analytics.stg_customersanalytics.stg_ordersanalytics.stg_payments)和两张表(analytics.customersanalytics.orders)。

$ dbt run07:28:43  Running with dbt=1.0.107:28:43  Unable to do partial parsing because profile has changed07:28:43  Unable to do partial parsing because a project dependency has been added07:28:44  Found 5 models, 20 tests, 0 snapshots, 0 analyses, 172 macros, 0 operations, 3 seed files, 0 sources, 0 exposures, 0 metrics07:28:4407:28:44  Concurrency: 1 threads (target='dev')07:28:4407:28:44  1 of 5 START view model analytics.stg_customers................................. [RUN]07:28:44  1 of 5 OK created view model analytics.stg_customers............................ [SUCCESS 0 in 0.12s]07:28:44  2 of 5 START view model analytics.stg_orders.................................... [RUN]07:28:44  2 of 5 OK created view model analytics.stg_orders............................... [SUCCESS 0 in 0.08s]07:28:44  3 of 5 START view model analytics.stg_payments.................................. [RUN]07:28:44  3 of 5 OK created view model analytics.stg_payments............................. [SUCCESS 0 in 0.07s]07:28:44  4 of 5 START table model analytics.customers.................................... [RUN]07:28:44  4 of 5 OK created table model analytics.customers............................... [SUCCESS 0 in 0.16s]07:28:44  5 of 5 START table model analytics.orders....................................... [RUN]07:28:45  5 of 5 OK created table model analytics.orders.................................. [SUCCESS 0 in 0.12s]07:28:4507:28:45  Finished running 3 view models, 2 table models in 0.64s.07:28:4507:28:45  Completed successfully07:28:4507:28:45  Done. PASS=5 WARN=0 ERROR=0 SKIP=0 TOTAL=5

去 TiDB 数据库中验证下,是否真的创建成功。

结果显示多出了 customers 等五张表格或视图,并且表或视图中的数据也都转换完成。这里只展示 customers 的部分数据。

mysql> show tables;+---------------------+| Tables_in_analytics |+---------------------+| customers           || orders              || raw_customers       || raw_orders          || raw_payments        || stg_customers       || stg_orders          || stg_payments        |+---------------------+8 rows in set (0.00 sec)mysql> select * from customers;+-------------+------------+-----------+-------------+-------------------+------------------+-------------------------+| customer_id | first_name | last_name | first_order | most_recent_order | number_of_orders | customer_lifetime_value |+-------------+------------+-----------+-------------+-------------------+------------------+-------------------------+|           1 | Michael    | P.        | 2018-01-01  | 2018-02-10        |                2 |                 33.0000 ||           2 | Shawn      | M.        | 2018-01-11  | 2018-01-11        |                1 |                 23.0000 ||           3 | Kathleen   | P.        | 2018-01-02  | 2018-03-11        |                3 |                 65.0000 ||           4 | Jimmy      | C.        | NULL        | NULL              |             NULL |                    NULL ||           5 | Katherine  | R.        | NULL        | NULL              |             NULL |                    NULL ||           6 | Sarah      | R.        | 2018-02-19  | 2018-02-19        |                1 |                  8.0000 ||           7 | Martin     | M.        | 2018-01-14  | 2018-01-14        |                1 |                 26.0000 ||           8 | Frank      | R.        | 2018-01-29  | 2018-03-12        |                2 |                 45.0000 |....

生成文档

dbt 还支持生成可视化的文档,命令如下。

  1. 生成文档
$ dbt docs generate07:33:59  Running with dbt=1.0.107:33:59  Found 5 models, 20 tests, 0 snapshots, 0 analyses, 172 macros, 0 operations, 3 seed files, 0 sources, 0 exposures, 0 metrics07:33:5907:33:59  Concurrency: 1 threads (target='dev')07:33:5907:33:59  Done.07:33:59  Building catalog07:33:59  Catalog written to /home/ubuntu/jaffle_shop/target/catalog.json
  1. 开启服务
$ dbt docs serve07:43:01  Running with dbt=1.0.107:43:01  Serving docs at 0.0.0.0:808007:43:01  To access from your browser, navigate to:  http://localhost:808007:43:0107:43:0107:43:01  Press Ctrl+C to exit.

可以通过浏览器查看文档,其中包含 jaffle_shop 项目的整体结构以及所有表和视图的描述说明。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NdVusX94-1649816248322)(/media/when-tidb-meets-dbt/2.png)]

总结

TiDB 在 dbt 中的使用主要有以下几步:

  1. 安装 dbt 和 dbt-tidb
  2. 配置项目
  3. 编写 SQL 和 YML 文件
  4. 运行项目

目前,TiDB 支持 dbt 的版本在 4.0 以上,但根据 dbt-tidb 项目文档描述,低版本的 TiDB 在和 dbt 结合使用中还存在一些问题,例如:不支持临时表和临时视图、不支持 WITH 语法等。想要痛快的使用 dbt ,建议使用 TiDB 5.3 以上版本,此版本支持 dbt 的全部功能。

当 dbt 遇见 TiDB丨高效的数据转换工具让数据分析更简单相关推荐

  1. 一款全面高效的日志分析工具,操作更简单

    一款全面高效的日志分析工具,操作更简单     Eventlog Analyzer是用来分析和审计系统及事件日志的管理软件,能够对全网范围内的主机.服务器.网络设备.数据库以及各种应用服务系统等产生的 ...

  2. LiveMe x TiDB丨单表数据量 39 亿条,简化架构新体验

    近些年,由于互联网的快速发展以及线上需求的爆发,直播在国内已经成为一个非常成熟的商业模式.在娱乐.教育.办公等场景中涌现出许多优秀的视频直播产品.随着国内市场竞争日益白热化,加之企业出海渐成趋势,越来 ...

  3. 线程锁,进程锁以及分布式锁丨锁的实现及原理分析丨高效的使用

    线程锁.进程锁以及分布式锁 1. 线程锁 2. 进程锁 3. 分布式锁 [技术分享篇]线程锁,进程锁以及分布式锁丨锁的实现及原理分析丨高效的使用 更多精彩内容包括:C/C++,Linux,Nginx, ...

  4. 组织创新丨高效组织的十个发展准则

    我们处在一个不确定的时代,组织创新也随着商业模式变化在发生变革,很多组织擅长发现具体的问题,且有为解决问题设计的各种方案,但鲜有需遵守以保证组织创新和成长能力的发展准则.本文以十条组织发展准则为参考, ...

  5. 哈佛计算机科学专业大一新生的一天,哈佛大一新生的一天丨高效的时间管理者,学习就是休息~...

    原标题:哈佛大一新生的一天丨高效的时间管理者,学习就是休息~ 前有哈佛学霸"元气满满"的一周学习生活分享(点击查看→一个典型哈佛学霸的一周,可能跟你想象的不一样--),这次,作为大 ...

  6. python数值转换机_用于ETL的Python数据转换工具详解

    ETL的考虑 做 数据仓库系统,ETL是关键的一环.说大了,ETL是数据整合解决方案,说小了,就是倒数据的工具.回忆一下工作这么些年来,处理数据迁移.转换的工作倒 还真的不少.但是那些工作基本上是一次 ...

  7. 高效数据同步工具DataX的使用

    一.DataX 简介 DataX 是阿里云 DataWorks 数据集成 的开源版本,主要就是用于实现数据间的离线同步. DataX 致力于实现包括关系型数据库(MySQL.Oracle 等).HDF ...

  8. arcgis Card Conversion Tools(数据转换工具介绍)

    Card Conversion Tools(转换工具) 工具箱介绍 Arcgis Conversion Tools 提供了当下绝大多数地理空间数据和地理属性数据的各种数据格式之间的转换,我们常用的且移 ...

  9. “乐高式”自动驾驶研发开放平台,让开发更简单灵活高效

    一.2周构建自动驾驶研发平台的秘诀详解 自动驾驶商业化落地加速 中国自动驾驶行业目前面临两个较大的变化.首先,去年11月北京正式开放自动化驾驶的商业化试点,这意味着自动化服务迈过了商业化门槛.与此同时 ...

  10. python etl 大猩猩_用于ETL的Python数据转换工具详解

    ETL的考虑 做 数据仓库系统,ETL是关键的一环.说大了,ETL是数据整合解决方案,说小了,就是倒数据的工具.回忆一下工作这么些年来,处理数据迁移.转换的工作倒 还真的不少.但是那些工作基本上是一次 ...

最新文章

  1. RDKit | 基于RDKit计算3D药效团指纹
  2. python交作业的格式_python作业4
  3. Android反编译技术总结
  4. Laravel 使用 scout 集成 elasticsearch 做全文搜索
  5. 关于Object数组强转成Integer数组的问题:Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;...
  6. windows下安装mongodb4.x版本
  7. java json serialize_java-是否可以简化@JsonSerialize注释?
  8. pic单片机用c语言怎么编程,手把手教你学PIC单片机C语言指导教程.pdf
  9. 计算机终端保密检查 玩游戏,计算机终端保密检查系统
  10. 小小精彩的flash
  11. origin 截断y轴
  12. 1等于0.循环9吗?
  13. 超链接一般有两种表现形式_超级链接有哪些常见的表现形式?
  14. js代码 实现购物车功能
  15. Beats:在 Docker 里运行 Filebeat
  16. linux原理与应用 武汉大学,Linux原理与应用(计算机科学与技术系列教材)
  17. 为什么卸载TeamViewer
  18. 平板win10 android哪个耗电,买平板电脑时,应该选win10还是安卓系统?
  19. PTA IP地址转换 简单方法Java
  20. 酒店民宿如何在小红书上精细化推广?

热门文章

  1. CS-Notes 知识清单 备战版
  2. 如何申请微信公众平台帐号
  3. 激活 win10 企业版2016长期服务版本
  4. 手机相机好坏测试软件,如何选择好的手机相机?一分钟教你看懂好与坏
  5. 温度传感器DS18B20的相关介绍以及基于MSP430的驱动程序(附代码)
  6. 你控制不了情绪,怎么过得好这一生?
  7. 2023计算机毕业设计SSM最新选题之javaJava班级信息管理系统x0w9c
  8. cygwin安装配置apt-cyg工具
  9. Excel 计算各种物料 平均采购价格
  10. 全新版大学英语综合教程第二册学习笔记(原文及全文翻译)——5A - True Height(真正的高度)