SQLMesh 系列教程9- 宏变量及内置宏变量

SQLMesh 的宏变量是一个强大的工具,能够显著提高 SQL 模型的动态化能力和可维护性。通过合理使用宏变量,可以实现动态时间范围、多环境配置、参数化查询等功能,从而简化数据模型的开发和维护流程。随着数据团队的规模扩大和业务复杂度的增加,宏变量的重要性将愈发凸显。

介绍宏变量

SQLMesh 是一个开源的数据转换框架,旨在简化 SQL 数据模型的设计、维护和部署流程。它通过引入 DevOps 最佳实践,支持多引擎、虚拟环境和数据血缘分析等功能,帮助数据团队高效管理数据模型。在 SQLMesh 中,宏变量(Macro Variables)是一个重要的特性,用于在 SQL 模型中实现动态化和可重用性。以下将详细介绍 SQLMesh 的宏变量,并结合示例说明其用法和优势。

宏变量的定义与作用

宏变量是 SQLMesh 中用于动态替换值的占位符,允许用户在 SQL 模型中定义可重用的逻辑。它们的主要作用包括:

  • 动态化 SQL 逻辑:通过宏变量,可以在运行时动态替换 SQL 中的值,避免硬编码。
  • 提高代码复用性:将常用的逻辑封装为宏变量,减少重复代码。
  • 简化维护:通过集中管理宏变量,降低维护成本。

SQLMesh 的宏变量通常以 @$ 开头,并在 SQL 模型中被引用。宏变量的值可以在模型定义、运行时或配置文件中指定14。

宏变量的分类

在 SQLMesh 中,宏变量可以分为以下几类:

  • 内置宏变量 :SQLMesh 提供了一些预定义的宏变量,例如 @start_date@end_date,用于处理时间范围相关的逻辑。
  • 用户自定义宏变量:用户可以根据需求定义自己的宏变量,并在 SQL 模型中引用。
  • 环境变量:SQLMesh 支持从环境变量中读取值,并将其作为宏变量使用。

宏变量的使用场景

宏变量在 SQLMesh 中的应用场景非常广泛,以下是一些典型用例:

  • 动态时间范围 :在增量模型中,使用 @start_date@end_date 动态指定时间范围。
  • 多环境配置:通过宏变量区分开发、测试和生产环境,例如动态切换数据库连接。
  • 参数化查询:在查询中使用宏变量实现参数化,避免 SQL 注入风险。
  • 代码复用:将复杂的逻辑封装为宏变量,供多个模型调用。

举例说明

宏变量是占位符,其值在呈现宏时被替换。它们支持动态宏行为------例如,日期参数的值可能基于宏运行的时间。

考虑一个在WHERE子句中按日期过滤的SQL查询。与每次运行模型时手动更改日期不同,您可以使用宏变量使日期动态。使用动态方法,日期会根据查询的运行时间自动更改。

这个查询过滤列my_date在'2023-01-01'之后的行:

sql 复制代码
SELECT *
FROM table
WHERE my_date > '2023-01-01'

要使这个查询的日期动态,你可以使用预定义的SQLMesh宏变量@execution_ds:

sql 复制代码
SELECT *
FROM table
WHERE my_date > @execution_ds

@符号告诉SQLMesh, @execution_ds是一个宏变量,需要在执行SQL之前进行替换。

宏变量@execution_ds是预定义的,因此它的值将由SQLMesh根据执行开始的时间自动设置。如果模型在2023年2月1日执行,呈现的查询将是:

sql 复制代码
SELECT *
FROM table
WHERE my_date > '2023-02-01'

这个例子使用了SQLMesh的一个预定义变量,但是你也可以定义自己的宏变量。

我们将在下面描述SQLMesh的预定义变量;在SQLMesh宏和Jinja宏页面中讨论了用户定义的宏变量。

内置宏变量

SQLMesh附带了可以在查询中使用的预定义变量。它们由SQLMesh运行时自动设置。

大多数预定义变量都与时间相关,并使用前缀(start、end等)和后缀(date、ds、ts等)的组合。它们将在下一节中描述;下一节将讨论其他预定义变量。

时间变量

SQLMesh使用python datetime模块来处理日期和时间。它使用标准的Unix纪元开始符1970-01-01。

前缀:

  • start - 包括模型运行的启动区间
  • end - 包括模型运行的结束区间
  • execution - 执行开始的时间戳

后缀:

  • dt - Python 的 datetime 对象,可转换为原生的 SQL TIMESTAMP(或等效的 SQL 引擎类型)
  • date - Python 的 date 对象,可转换为原生的 SQL DATE
  • ds - 格式为 '%Y-%m-%d' 的日期字符串
  • ts - 格式为 '%Y-%m-%d %H:%M:%S' 的 ISO 8601 日期时间格式字符串
  • tstz - 格式为 '%Y-%m-%d %H:%M:%S%z' 的带有时区的 ISO 8601 日期时间格式字符串
  • hour - 表示一天中的小时数的整数,取值范围为 0 到 23
  • epoch - 表示自 Unix 纪元以来的秒数的整数
  • millis - 表示自 Unix 纪元以来的毫秒数的整数

所有预定义的时间宏变量:

  • dt
    • @start_dt
    • @end_dt
    • @execution_dt
  • date
    • @start_date
    • @end_date
    • @execution_date
  • ds
    • @start_ds
    • @end_ds
    • @execution_ds
  • ts
    • @start_ts
    • @end_ts
    • @execution_ts
  • tstz
    • @start_tstz
    • @end_tstz
    • @execution_tstz
  • hour
    • @start_hour
    • @end_hour
    • @execution_hour
  • epoch
    • @start_epoch
    • @end_epoch
    • @execution_epoch
  • millis
    • @start_millis
    • @end_millis
    • @execution_millis

运行时变量

SQLMesh提供了另外两个预定义变量,用于根据运行时可用的信息修改模型行为。

  • @runtime_stage --- 字符串值,表示SQLMesh运行时的当前阶段。通常在模型中用于有条件地执行pre/post语句(在这里了解更多)。它返回以下值之一:

    • loading - 项目正在加载到 SQLMesh 的运行时上下文中。

    • creating - 模型表正在创建。

    • evaluating - 模型查询逻辑正在评估。

    • promoting - 模型正在目标环境中推广(虚拟层更新)。

    • auditing - 正在运行审计。

    • testing - 模型查询逻辑正在单元测试的上下文中评估。

  • @gateway --- 包含当前网关名称的字符串值。

  • @this_model --- 字符串值,包含模型视图选择的物理表的名称。通常用于创建通用审核。在on_virtual_update语句的情况下,它包含限定视图名称。

    • 当SQLGlot不能完全解析语句,需要直接引用模型的底层物理表时,可以在模型定义中使用。

    • 可以作为参数传递给访问或与底层物理表交互的宏。

实战案例

以下是一个完整的示例,展示如何在 SQLMesh 中使用宏变量实现动态时间范围和多环境配置。

1. 项目配置
yaml 复制代码
gateways:
  prod_gateway:
    connection:
      type: duckdb
      database: prod.db

  dev_gateway:
    connection:
      type: duckdb
      database: dev.db

default_gateway: dev_gateway
2. 定义模型
sql 复制代码
MODEL (
    name example.incremental_model,
    owner Yuki,
    kind INCREMENTAL_BY_TIME_RANGE (
        time_column (updated_date, '%Y-%m-%d'),
        lookback 5,
    ),
    start '2025-01-01',
    cron '@daily',
    grain id,
    column_descriptions (
        id = 'primary key',
        letter = 'alphabet letter',
        updated_date = 'updated date',
    )
);
3. 引用宏变量
sql 复制代码
SELECT
    id,
    letter,
    updated_date
FROM
    example.base_model
WHERE
    updated_date BETWEEN @start_date AND @end_date
    AND @gateway = 'prod_gateway';
4. 运行计划
shell 复制代码
sqlmesh plan --gateway prod_gateway

最后总结

SQLMesh 的宏变量是用于动态替换值的占位符,允许用户在 SQL 模型中定义可重用的逻辑。它们的主要作用包括动态化 SQL 逻辑、提高代码复用性和简化维护。SQLMesh 的宏变量可以分为内置宏变量、用户自定义宏变量和环境变量。宏变量在 SQLMesh 中的应用场景非常广泛,包括动态时间范围、多环境配置、参数化查询和代码复用。通过合理使用宏变量,可以显著提高 SQL 模型的动态化能力和可维护性。

相关推荐
梦想画家11 天前
SQLMesh 系列教程4- 详解模型特点及模型类型
数据工程·sqlmesh
梦想画家13 天前
SQLMesh系列教程-3:SQLMesh模型属性详解
数据工程·分析工程
梦想画家1 个月前
Airflow:深入理解Apache Airflow 调度器
数据集成·airflow·数据工程
梦想画家1 个月前
Airflow:TimeSensor感知时间条件
数据集成·数据工程
梦想画家2 个月前
Airflow:HttpSensor实现API驱动数据流程
数据集成·airflow·数据工程
梦想画家2 个月前
Airflow:如何使用jinja模板和宏
数据集成·airflow·jinja·数据工程
梦想画家2 个月前
DuckDB:JSON数据探索性分析实战教程
数据分析·json·数据工程·duckdb·分析工程
梦想画家2 个月前
DuckDB: 从MySql导出数据至Parquet文件
数据工程·duckdb·分析工程
梦想画家2 个月前
DuckDB快速入门教程
数据工程·duckdb·分析工程