SQLMesh系列教程-2:SQLMesh入门项目实战(上篇)

server/2025/2/12 20:50:16/

假设你已经了解SQLMesh是什么,以及其他应用场景。如果没有,我建议你先阅读《SQLMesh系列教程-1:数据工程师的高效利器-SQLMesh》。

在本文中,我们将完成一个小项目或教程,以帮助你开始使用SQLMesh。你可以选择一步一步地进行操作,也可以通读一遍以了解整个过程。

在这里插入图片描述

搭建开发环境

你可以使用自己喜欢的IDE,但在本教程中我将使用VSCode。我们将使用duckdb作为执行引擎和数据源。如果你对duckdb在CLI和Python开始使用感兴趣,请搜索我的其他duckdb系列文章。

首先,让我们通过安装Python和必要的依赖项来设置工作环境。创建一个Python虚拟环境并安装依赖项:

python -m venv .venv
source ./venv/bin/activate
pip install 'sqlmesh[duckdb]'

我们将使用一个简单的数据集来重点理解SQLMesh。让我们在duckdb CLI中创建一个源数据库(也可以在Python中执行相同的操作)。我将使用名称“db.db”,因为它是初始化duckdb项目时SQLMesh配置的默认名称:

duckdb db.db

创建schema及源表:

CREATE SCHEMA example;
CREATE OR REPLACE TABLE example.letters (id INTEGER, letter CHAR(1), value INTEGER, updated_date DATE); -- 插入数据
INSERT INTO example.letters VALUES (1, 'A', 10, '2025-01-07'), (2, 'B', 20, '2025-01-07'), (3, 'C', 30, '2025-01-07');

检查表数据:

SELECT * FROM example.letters;┌───────┬─────────┬───────┬──────────────┐
│  id   │ letter  │ value │ updated_date │
│ int32 │ varchar │ int32 │     date     │
├───────┼─────────┼───────┼──────────────┤
│     1 │ A       │    102025-01-07   │
│     2 │ B       │    202025-01-07   │
│     3 │ C       │    302025-01-07   │
└───────┴─────────┴───────┴──────────────┘

初始化SQLMesh项目

在命令行中,执行以下命令初始化sqlmesh项目:

sqlmesh init duckdb

一旦你运行这个命令,你会看到生成了几个文件夹,就像你初始化dbt项目时一样:

在这里插入图片描述

sqlmesh_61">解释sqlmesh项目结构

在上面的截图中,您可以看到多个文件夹,例如:

  • “audits” - 用于定义自定义数据审计的SQL文件
  • “logs” - (运行项目后你会看到)-日志文件
  • “macros” - Python文件用于Python宏,SQL文件用于Jinja宏
  • “models” - SQL或Python文件/模型将被存储
  • “seeds” - 静态CSV文件
  • “tests” - 定义单元测试的yaml文件

你还可以看到“config.yaml”。配置SQLMesh项目设置的文件。让我们看下配置文件内容:

gateways:local:connection:type: duckdbdatabase: db.dbdefault_gateway: localmodel_defaults:dialect: duckdbstart: 2025-02-09

这是配置数据库连接的地方。SQLMesh用duckdb作为后端初始化项目的上述内容。

基本上就是说,SQLMesh在默认情况下使用名为“local”的网关,在使用duckdb SQL方言的名为“db.db”的数据库中使用duckdb作为其执行引擎。正如你可能已经猜到的,你可以在这个配置文件中分离测试连接和状态数据库连接。

现在,让我们稍微修改一下这个配置文件,添加一个单独的test/state连接:

gateways:local:connection:type: duckdbdatabase: db.dbtest_connection:type: duckdbdatabase: test.dbstate_connection:type: duckdbdatabase: state.dbdefault_gateway: localmodel_defaults:dialect: duckdbstart: 2025-02-09

我指定使用“test.db”运行测试,使用“state.db”管理状态信息。现在我们有了一个整体的结构,让我们来为一个演示目构建模型、宏、审计和测试。

从头设计数据模型

我们将构建模型、Python宏、审计和测试。在初始化的SQLMesh项目中,有3个模型:

  • seed_model.sql
  • incremental_model.sql
  • full_model.sql

种子模型是静态的,为了使我们的项目更有意义,我们将使用我们在前一步中生成的一些数据完全替换种子模型。我们还将用新产品替换其他两种型号。

之后,我们将执行模型并创建一个简单的Python宏、一个自定义审计和一个单元测试。我们将看到所有这些如何很好地协同工作。

让我们删除“seed_model”。Sql”文件。您可以手动执行或运行命令:

rm models/*.sql

让我们创建一个新模型,它将作为其他两个模型的基础。我们已经在“db.db”中创建了一个源表,它被设置为SQLMesh项目的连接数据库。

建立基础模型

我将这个模型命名为“base_model.sql”:

MODEL (name example.base_model,owner tom,kind VIEW,cron '@daily',grain id,column_descriptions (id = 'primary key',letter = 'alphabet letter',value = 'random value'));SELECTid::INT,letter::TEXT,value::INT,updated_date
FROM 
db.example.letters  -- full table path

需要注意的一些事情:

  • 模型元数据直接进入模型文件,而不是像在dbt中那样在单独的yaml文件中定义所有内容。
  • 你可能不熟悉元数据,如“kind”,“owner”,“cron”和“grain”,但它们是相当不言自明的。虽然‘ cron ’将在运行‘ sqlmesh run ’时使用,我们将在后面介绍。你可以在SQLMesh的文档页面上查看可用的模型属性。
  • 类型转换是使用Postgres的‘ x::int ’语法完成的。您还可以在‘ MODEL ’块中指定模式(列名=数据类型)。
  • 你可以通过添加类似“id::INT -主键”这样的注释来添加列描述,但我喜欢将列描述放在“MODEL”块中。
  • 如果您引用的是SQLMesh项目之外的表,它将被视为外部表,你需要指定表路径,而不是模型名称。

外部模型

可选地,你可以创建/生成一个external_models。用于存储外部表的元数据。定义外部模型的元数据的好处是,SQLMesh可以使特性更有用。例如,如果你没有创建yaml文件,那么你将无法获得到外部模型的列级沿袭。

创建external_models。您可以手动定义Yaml,也可以运行以下命令:

sqlmesh create_external_models 

SQLMesh将创建一个yaml文件,如下所示:

- name: '"db"."example"."letters"'columns:id: INTletter: TEXTvalue: INTupdated_date: DATEgateway: local

建立下游模型

既然基本模型已经准备好了,其外部模型模式信息也已经到位,那么让我们创建更多的模型。

  • “example.intermediate_model.sql” - 这个模型类似于“base_model.sql”,除了它包括一个新的列,改变了它只需要指定上游表的模型名,并使用‘ FULL ’物化策略:
MODEL (name example.intermediate_model,owner tommy,kind FULL,cron '@daily',grain id,column_descriptions (id = 'primary key',letter = 'alphabet letter',value = 'random value',updated_date = 'updated date',new_col = 'a new column'));SELECTid,letter,value,@multiply_by_10(value) AS big_value,updated_date,'new_col' AS new_colFROMexample.base_model

“example.incremental_model。- 该模型使用‘ INCREMENTAL_BY_TIME_RANGE ’物化策略,这是SQLMesh中3个增量加载选项之一。这需要添加where子句,以确保只处理必要的数据。

MODEL (name example.incremental_model,owner tommy,kind INCREMENTAL_BY_TIME_RANGE (time_column (updated_date, '%Y-%m-%d'),lookback 5,  -- to handle late arriving date),start '2025-01-01',cron '@daily',grain id,column_descriptions (id = 'primary key',letter = 'alphabet letter',updated_date = 'updated date',));SELECTid,letter,updated_dateFROMexample.base_modelWHERE updated_date BETWEEN @start_date AND @end_date

我不会太深入SQLMesh的增量加载选项,但简单地说,你可以使用增量加载数据:

  • by time range
  • by partition
  • by unique key (a merge operation)

sqlmesh_plan_264">使用“sqlmesh plan”应用更改

现在已经构建了我们的模型,我们将使用‘ sqlmesh plan ’命令查看更改并加载数据。

注意:`test_full_model。我们初始化项目时附带的Yaml '文件应该删除,因为它不再适用于我们的项目。如果尝试在不删除yaml文件的情况下运行下面的命令,可能会遇到错误。因此,请确保在继续之前将其从项目中删除。

首先运行下面命令:

sqlmesh plan dev

系统将询问您希望回填多少数据的日期范围,但通过按回车键将其保留为空白。对于最后一个问题,输入“y”以应用更改:

在这里插入图片描述

执行过程截图:

在这里插入图片描述

为了确保你的模型被物化,你可以进入你的数据库或使用‘ sqlmesh fetchdf ’命令:

$ sqlmesh fetchdf "select * from example__dev.base_model;"id letter  value updated_date
0   1      A     10   2025-01-07
1   2      B     20   2025-01-07
2   3      C     30   2025-01-07

注意,我必须将模式指定为example__dev。模式的格式是YOURSCHEMA__{yourenenvironment}。在这种情况下,我运行sqlmesh plan dev ,并添加了__dev后缀。

如果一切正常,那么你可以通过运行以下命令将更改部署到生产环境:

sqlmesh plan

在这里插入图片描述
检查生产环境中的base_model表(schema没有后缀):

$ sqlmesh fetchdf "select * from example.base_model;"id letter  value updated_date
0   1      A     10   2025-01-07
1   2      B     20   2025-01-07
2   3      C     30   2025-01-07

你可能已经注意到,当我们运行‘ sqlmesh plan ’时,我们不需要回填任何数据。SQLMesh只是通过使用视图将指针切换到更新后的表。

现在,在实际项目中,顺序运行‘ sqlmesh plan dev ’和‘ sqlmesh plan ’可能不是你部署到生产环境的方式。好消息是SQLMesh有一个开源的GitHub Actions CI/CD Bot。它的功能如下:

自动在pr上运行单元测试

  • 自动创建PR环境,表示PR中的代码更改
  • 自动分类和回填数据的模型已经改变
  • 自动将更改部署到生产中,自动防止数据差距并合并PR

这些要点是从SQLMesh网站上复制粘贴过来的,在未来文章中我们继续讨论。

sqlmesh_run_326">sqlmesh run

当我第一次开始使用SQLMesh时,我有一个问题:sqlmesh plansqlmesh run 之间的区别是什么?

  • sqlmesh plan ’汇总本地所有变更,并允许你在目标环境中检查和执行模型。
  • sqlmesh run ’根据每个cron时间表执行模型。对我来说,除了SQLMesh利用模型属性中定义的“cron”之外,更容易认为它是“dbt run”。例如,假设你有一个具有每日cron计划的模型和另一个具有小时cron计划的模型。你计划通过GitHub Actions每小时运行“sqlmesh run”命令。使用每日cron计划的模型每天只运行一次,而如果您每小时运行“dbt run”,则所有模型每小时运行一次,从而导致浪费计算资源。

现在我们已经介绍了两个关键的SQLMesh命令,让我们继续学习我们的教程/项目。

总结

本文我们首先搭建duckdb及sqlmesh基础开发环境,然后新建入门项目,解释项目结构,构建数据模型,执行模型并查看结果。为了避免文章篇幅太长,关于宏、审计、测试,数据血缘关系及DAG, python模型。


http://www.ppmy.cn/server/167147.html

相关文章

详解策略模式

引言 实现一个目标往往有多种方式,比如从上海到北京,可以选择高铁、火车、飞机、自驾等等。同样实现一个功能我们可能也有多种方法,把这些方法封装为算法,根据不同的需求选择不同的算法(策略),让…

【人工智能】如何在VSCode中使用DeepSeek?

文章目录 前言一、准备工作二、安装DeepSeek插件步骤1、扩展图标搜索DeepSeep2、安装DeepSeek插件3、使用测试DeepSeekBito文心一言 结论 前言 介绍在VSCode中调用DeepSeek插件工具,可以进行对话、编码。 一、准备工作 确保已经安装好了VSCode软件。 二、安装D…

DevOps的个人学习

一、DevOps介绍 软件开发最初是由两个团队组成: 开发团队:负责设计和构建系统。运维团队:负责测试代码后部署上线,确保系统稳定安全运行。 这两个看似目标不同的团队需要协同完成一个软件的开发。DevOps整合了开发与运维团队&a…

性格测评小程序03搭建用户管理

目录 1 创建数据源2 搭建后台3 开通权限4 搭建启用禁用功能最终效果总结 性格测评小程序我们期望是用户先进行注册,注册之后使用测评功能。这样方便留存用户的联系信息,日后还可以推送对应的相关活动促进应用的活跃。实现这个功能我们要先创建数据源&…

uni-app vue3 使用笔记

1.弹窗、加载、请求接口 <template><view><view class"tn-type-primary_bg" v-if"item.roleId16" click"confirmMarker(item.uid)">指定营销员</view></view></template><script setup lang"ts&qu…

3. Strategy(策略模式)C++

3. Strategy&#xff08;策略模式&#xff09;C 策略模式属于“组件协作”模式里的一种。 1. 动机 举个例子&#xff0c;我们假设一个场景&#xff0c;做一个税种的计算&#xff0c;一个跨国的税计算&#xff0c;除了涉及金额等&#xff0c;还需要考虑不同国家的纳税比例。 /…

java项目之直销模式下家具工厂自建网站源码(ssm+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的直销模式下家具工厂自建网站源码。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 直销模式下家具…

简化API 工作流程:Apipost整合了 Postman、Swagger 和 JMeter

作为一名Java开发者&#xff0c;始终追求开发过程的高效性。使用IntelliJ IDEA编写代码只是开始。一般来说&#xff0c;代码完成后&#xff0c;我们会切换到Postman进行API调试。在确保API表现符合预期后&#xff0c;我们会使用Swagger为前端团队生成文档。最后&#xff0c;再使…