SQLGlot:用SQLGlot解析SQL

几十年来,结构化查询语言(SQL)一直是与数据库交互的实际语言。在一段时间内,不同的数据库在支持通用SQL语法的同时演变出了不同的SQL风格,也就是方言。这可能是SQL被广泛采用和流行的原因之一。

SQL解析是解构SQL查询以提取不同信息的过程,如字段、表、过滤器、连接等。查询解析主要由优化器组件在所有数据库后端中使用,以了解如何优化查询以进行处理。数据库优化器查询解析的细节超出了本文的讨论范围。我们在这里的目的是了解SQL解析的各种用例(在数据库引擎之外),并探索SQLGlot如何提供帮助。

SQLGlot介绍

来自官方文档:SQLGlot是一个无依赖性SQL解析器、转译器、优化器和引擎。

这支持:

  • SQL格式化
  • 20种不同的方言
  • 方言转换
  • 自定义解析器实现
  • 查询分析
  • 还有更多……

我使用这个包进行SQL解析,从给定的SQL查询中提取信息。我尝试了其他软件包,如sqlparse,发现sqlglot更好。
在这里插入图片描述

SQL解析应用场景

→数据健康监控/数据可观察性:分析数据库查询历史,提取使用频次高的表和列、未使用表和列、以及表之间关系等信息。

→方言翻译:SQL解析通常产生一个AST(抽象语法树)输出,该输出与数据库无关,可用于将给定查询翻译为不同的SQL方言。

→数据目录:SQL 解析器可用于通过提取诸如特定表上运行的常见查询、用户/组对表的使用情况、查询模式等信息来填充数据目录,从而提高数据集的可发现性。数据目录是一个集中化的元数据存储系统,用于管理和描述组织内的各种数据资产(如数据库表、文件、API等)。它的主要目的是帮助数据使用者(如数据分析师、数据科学家)快速找到和理解他们需要的数据。

→业务规则提取和文档:提取业务规则,ETL转换等,可用于自动生成这些规则的文档,帮助自助数据发现和分析。

→SQL可视化和优化:查询树的快速分析有助于识别执行SQL中的问题和反模式。这对于没有经验的用户/SQL生成工具(如BI可视化工具中可用的那些)生成错误的SQL查询特别有用。

→SQL格式化:可能是SQL解析器最常见的用例。有助于格式化SQL查询的可读性和确定优化的领域。

SQL解析简单示例

从任何给定的SQL中提取表名、数据库名:

from sqlglot import parse_one, exp

query = """
SELECT
col1
,col2
,col3
FROM db1.table1
"""
for table in parse_one(query).find_all(exp.Table):
  print(f"Table => {table.name} | DB => {table.db}")

从任何给定的SQL中提取表名、数据库名:

from sqlglot import parse_one, exp
query = """
SELECT
col1
,col2
,col3
FROM db1.table1
"""
for column in parse_one(query).find_all(exp.Column):
  print(f"Column => {column.name}")

查找CTE到表的关系(在构建血缘关系/查询DAG时可能很有用):

query = """
with tab1 as
(
  select a,b from db1.table1
)
,tab2 as
(
  select a from tab1
)
,tab3 as
(
  select
  t1.a
  ,t2.b
  from tab1 t1
  join tab2 t2
  on t1.a = t2.a
)
select
*
from tab3
"""

dependencies = {}

for cte in parse_one(query).find_all(exp.CTE):
  dependencies[cte.alias_or_name] = []

  cte_query = cte.this.sql()
  for table in parse_one(cte_query).find_all(exp.Table):
    dependencies[cte.alias_or_name].append(table.name)
print(dependencies)

-- Output: {'tab1': ['table1'], 'tab2': ['tab1'], 'tab3': ['tab1', 'tab2']}

SQLGlot详细示例

  • 数据库迁移

当应用从一个数据库系统迁移到另一个数据库系统时,通常需要将现有的 SQL 查询语句转换为目标数据库系统的语法。SQLGlot 可以帮助简化这个过程,使得迁移过程更加顺利。

import sqlglot
sql = "SELECT EPOCH_MS(1618088028295)"
transformed_sql = sqlglot.transpile(sql, read="duckdb", write="hive")[0]
print(transformed_sql)
# 输出: SELECT FROM_UNIXTIME(1618088028295 / 1000)
  • 跨平台开发

在跨平台开发中,不同的平台可能使用不同的数据库系统。SQLGlot 可以帮助开发人员编写一次 SQL 查询语句,然后通过转换功能将其适配到不同的数据库系统上,从而减少重复工作。

import sqlglot
sql = "SELECT * FROM users WHERE age > 30 AND city = 'New York'"
transformed_sql_mysql = sqlglot.transpile(sql, dialect="mysql")[0]
transformed_sql_postgresql = sqlglot.transpile(sql, dialect="postgresql")[0]
print("转换为MySQL语法:", transformed_sql_mysql)
print("转换为PostgreSQL语法:", transformed_sql_postgresql)

  • 数据库查询工具

一些数据库查询工具可能需要支持多种数据库系统,而用户可能希望在不同数据库系统上执行相同的查询。SQLGlot 可以帮助这些工具实现跨数据库的查询支持。

import sqlglot
sql = "SELECT * FROM users WHERE age > 30 AND city = 'New York'"
transformed_sql = sqlglot.transpile(sql, dialect="bigquery")[0]
print(transformed_sql)

  • SQL 语句优化

在数据库开发中,经常会遇到需要优化的查询语句。SQLGlot 可以帮助开发者重写查询语句,优化查询逻辑和执行计划,提高查询效率。

from sqlglot import optimize
sql = "SELECT * FROM users WHERE age > 30 AND city = 'New York'"
optimized_sql = optimize(sql)
print(optimized_sql)

  • 索引优化建议

SQLGlot 可以分析查询语句中的索引使用情况,提出索引优化建议,帮助开发者优化数据库表结构和索引设计。

from sqlglot import index_suggestions
sql = "SELECT * FROM users WHERE age > 30 AND city = 'New York'"
index_suggestions = index_suggestions(sql)
print(index_suggestions)

  • 实时数据分析

SQLGlot 可以结合实时数据流处理框架(如 Apache Kafka、Apache Flink 等),实现实时数据分析和处理,满足大规模数据处理和分析的需求。

from sqlglot import transform
sql = "SELECT * FROM streaming_data WHERE value > 100"
transformed_sql = transform(sql)
print(transformed_sql)

  • 数据血缘分析

通过解析 SQL 查询,SQLGlot 可以提取表和字段级别的信息,帮助构建数据血缘图,了解数据的来源和流向。

from sqlglot import parse_one, exp
query = """
SELECT col1, col2, col3
FROM db1.table1
"""
for table in parse_one(query).find_all(exp.Table):
    print(f"Table => {table.name} | DB => {table.db}")
for column in parse_one(query).find_all(exp.Column):
    print(f"Column => {column.name}")

  • 复杂查询解析

SQLGlot 可以解析复杂的查询,包括 CTE(Common Table Expressions)和多表连接查询,帮助开发者理解和优化这些查询。

from sqlglot import parse_one, exp
query = """
WITH tab1 AS (
    SELECT a, b FROM db1.table1
),
tab2 AS (
    SELECT a FROM tab1
),
tab3 AS (
    SELECT t1.a, t2.b
    FROM tab1 t1
    JOIN tab2 t2 ON t1.a = t2.a
)
SELECT * FROM tab3
"""
dependencies = {}
for cte in parse_one(query).find_all(exp.CTE):
    dependencies[cte.alias_or_name] = []
    cte_query = cte.this.sql()
    for table in parse_one(cte_query).find_all(exp.Table):
        dependencies[cte.alias_or_name].append(table.name)
print(dependencies)

SQLGlot 官方文档

有关SQL格式、方言翻译、查询验证的其他示例,请参阅官方文档。(链接如下)。

SQLGlot Official Documentations

  • API documentation
  • Official Github

最后总结

SQLGlot 是一个功能强大的工具,适用于多种数据库开发和数据分析场景。它不仅支持 SQL 语句的解析、转换和优化,还能够帮助开发者进行数据血缘分析、索引优化和实时数据分析。通过这些功能,SQLGlot 可以显著提高开发效率,优化数据库操作,并支持跨数据库的兼容性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/963853.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 大视界 -- Java 大数据在智能电网中的应用与发展趋势(71)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

想表示消息返回值为Customer集合

道奈特(240***10) 14:34:55 EA中序列图。我想表示消息返回值为 Customer 集合。目前只有一个Customer实体类,我需要另外新建一个CustomerList 类吗? 潘加宇(35***47) 17:01:26 不需要。如果是分析,在类的操作中,定义一个参数&…

01.双Android容器解决方案

目录 写在前面 一,容器 1.1 容器的原理 1.1.1 Namespace 1.1.2 Cgroups(Control Groups) 1.1.3 联合文件系统(Union File System) 1.2 容器的应用 1.2.1 微服务架构 1.2.2 持续集成和持续部署(CI/…

【Elasticsearch】硬件资源优化

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

2025-工具集合整理

科技趋势 github-rank 🕷️Github China/Global User Ranking, Global Warehouse Star Ranking (Github Action is automatically updated daily). 科技爱好者周刊 制图工具 D2 D2 A modern diagram scripting language that turns text to diagrams 文档帮助 …

二叉树--链式存储

1我们之前学了二叉树的顺序存储(这种顺序存储的二叉树被称为堆),我们今天来学习一下二叉树的链式存储: 我们使用链表来表示一颗二叉树: ⽤链表来表⽰⼀棵⼆叉树,即⽤链来指⽰元素的逻辑关系。通常的⽅法是…

Java 23新特性

文章目录 Java 23新特性一、引言二、Markdown文档注释(JEP 467)示例 三、ZGC:默认的分代模式(JEP 474)1. 为什么要引入分代模式2. 使用分代模式的优势3. 如何启用分代模式 四、隐式声明的类和实例主方法(JE…

【数据结构】_链表经典算法OJ:复杂链表的复制

目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接:138. 随机链表的复制 - 力扣(LeetCode) 题目描述: 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,…

Shell篇-字符串处理

目录 1.变量引用 2.获取字符串长度 3.字符串截取 4.删除子字符串 5.字符串替换 总结: Bash(Shell 脚本)中的字符串处理语法。以下是对其的介绍和总结:Bash 变量可以使用不同的语法来获取、修改和删除字符串的内容。图片中列…

STM32 TIM定时器配置

TIM简介 TIM(Timer)定时器 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能&#xff…

Spring Security(maven项目) 3.0.2.9版本 --- 改

前言: 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往…

数据结构(1)——算法时间复杂度与空间复杂度

目录 前言 一、算法 1.1算法是什么? 1.2算法的特性 1.有穷性 2.确定性 3.可行性 4.输入 5.输出 二、算法效率 2.1衡量算法效率 1、事后统计方法 2、事前分析估计方法 2.2算法的复杂度 2.3时间复杂度 2.3.1定义 2.3.2大O渐进表示法 2.3.3常见时间复…

巧妙利用数据结构优化部门查询

目录 一、出现的问题 部门树接口超时 二、问题分析 源代码分析 三、解决方案 具体实现思路 四、优化的效果 一、出现的问题 部门树接口超时 无论是在A项目还是在B项目中,都存在类似的页面,其实就是一个部门列表或者叫组织列表。 从页面的展示形式…

pycharm 中的 Mark Directory As 的作用是什么?

文章目录 Mark Directory As 的作用PYTHONPATH 是什么PYTHONPATH 作用注意事项 Mark Directory As 的作用 可以查看官网:https://www.jetbrains.com/help/pycharm/project-structure-dialog.html#-9p9rve_3 我们这里以 Mark Directory As Sources 为例进行介绍。 这…

机器学习10

自定义数据集 使用scikit-learn中svm的包实现svm分类 代码 import numpy as np import matplotlib.pyplot as pltclass1_points np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4, 1.1]])class2_points np.array([[3.2, 3.2],[3.7, 2.9],…

二叉树——429,515,116

今天继续做关于二叉树层序遍历的相关题目,一共有三道题,思路都借鉴于最基础的二叉树的层序遍历。 LeetCode429.N叉树的层序遍历 这道题不再是二叉树了,变成了N叉树,也就是该树每一个节点的子节点数量不确定,可能为2&a…

WPF进阶 | WPF 样式与模板:打造个性化用户界面的利器

WPF进阶 | WPF 样式与模板:打造个性化用户界面的利器 一、前言二、WPF 样式基础2.1 什么是样式2.2 样式的定义2.3 样式的应用 三、WPF 模板基础3.1 什么是模板3.2 控件模板3.3 数据模板 四、样式与模板的高级应用4.1 样式继承4.2 模板绑定4.3 资源字典 五、实际应用…

六百六十六,盐豆不带盐了

我还有救吗...... P11040 #include <iostream> #include <vector> #include <cstring> using namespace std; const int MOD 998244353; const int MAXN 1e7 5; const int MAXM 1e7 5; int n, q; int m; int dpTable[MAXN][32]; int prefixSum[MAXN][32…

传输层协议 UDP 与 TCP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 前置复盘&#x1f98b; 传输层&#x1f98b; 再谈端口号&#x1f98b; 端口号范围划分&#x1f98b; 认识知名端口号 (Well-Know Port Number) 二&#xf…

LabVIEW无人机航线控制系统

介绍了一种无人机航线控制系统&#xff0c;该系统利用LabVIEW软件与MPU6050九轴传感器相结合&#xff0c;实现无人机飞行高度、速度、俯仰角和滚动角的实时监控。系统通过虚拟仪器技术&#xff0c;有效实现了数据的采集、处理及回放&#xff0c;极大提高了无人机航线的控制精度…