前言


写此sqlparse库的目的还是寻找在python编程内可行的SQL血缘解析,JAVA去解析Hive的源码实践的话我还是打算放到后期来做,先把Python能够实现的先实现完。上篇系列讲述的基于antrl解析说是用python其实还是太牵强了,无非就是使用PyJnius调用JAVA的类方法来实现,没有多大的意义来牵扯到Python编程。主要是HiveSQL的底层就是JAVA代码,怎么改写还是绕不开JAVA的。不过上篇系列我有提到过sqlparse,其实这个库用来解析血缘的话也不是不可以,但是能够实现的功能是有限的,目前我实验还行,一些复杂超过千行的数据分析SQL没有测试过。做一些简单的血缘解析的话还是没有应该太大问题,后续我会在此基础之上开发尝试。


一、sqlparse简介


首先先给官网地址: python-sqlparse 。有足够好编码能力可以直接上github上面看源码,解读更细: github.sqlparse


sqlparse是用于Python的非验证SQL解析器。它支持解析、拆分和格式化SQL语句。既然有解析功能那么我们就能做初步的血缘解析功能。这个库的函数解析没有像Pandas和numpy写的那么详细,毕竟是人家个人的开源库,功能写的已经很不错了,能够省去我们很多递归剥离AST树的时间。官网上关于该库使用操作很简单,很多比较好的功能函数也没有使用到,我希望可以尽力将此库开发为通用SQL血缘解析的基础工具库。如果该功能开发完我会将此项目开源。


我通过细读源码来了解此库的大体功能。


二、功能代码解析


1.初始方法


看初始化代码方法有四种:parse,parsestream,format,split这四种


1.parse

传入一个SQL语句,返回一个 sqlparse.sql.Statement的元组,我们可以递归方式获得输出。

0a1458538e3f4fb78e7fd47030c7d924.png

其元组根据;符号来进行切分存储:

1ad1766b825747bfbb74c483ec01dfd8.png


f034e91b8a3642d7a3247c1c81c8952a.png


2.parsestream


可以看到第一个方法是调用了parsestream来完成流式解析的,那么这个方法也就是循环读取sql语句来完成转换statment的:

这里的引擎是可以替换的。


24dafe92dbdc4a049fc4ea6e4ced8699.png


它将返回一个sqlparse.sql.Statement实例的发生器。来看看这个run方法:


该方法就是生产一个statment,这个类应该就是这个库的基类了,多半围绕这个数据结构来处理。


3.format


该方法就是将sql语句标准化:


48739bf7c2dd49ae979f426a7b047fe7.png


format()函数接受关键字参数:


keyword_case 关键词upper、lowersql的保留字大小写

identifier_case 标识符的upper、lower大小写

strip_comments=Ture删除注释

reindent=Ture美化sq缩进语句发生改变


4.split


该方法用于分割sql语句:



55cfa6d9345047d6996bfa37a4345568.png


这里补充一下calss类sqlparse.sql.Statement是可以直接通过str转换为字符串的。

结果返回一个分割后的list。至此初始方法就写完了,下面我将详解一下基类,这将决定是我们是否能灵活运用此库。


2.基类-Token


我们来看看Token的初始方法属性:



这个Token类也就是语法解析器的重点数据流了:

5ee0df906fcf4cf39f29c525e8c28974.png

此类需要生成Tokens使用,这牵扯到另一个方法tokens.py:

此方法也就是将statment类转换为Token流:


7dbc3a7fa580452ba005bc11d4b5367d.png


其中我们需要解析的每个Token的标识码也就是第一个ttype属性,解析之后:


1. for each_token in sql_tokens:
2. print(each_token.ttype,each_token.value)


f84a5abe5dd647c0af6ecf23714782aa.png


我们拿一个Token来研究就能逐渐解析到其他token。我们建立一个列表将其主要属性ttype和value收集起来:

第一个属性为sqlparse.tokens._TokenType第二个value直接就是str了。上tokens看_TokenType:

可以发现这就是Token的识别解析类型码,通过该码就可以访问获得解析出的关键字了。

关于此基类又有五种主要的方法:


1. flatten ()


用于解析子组

5c80ab4c17a54220900792fe7c24145e.png

2. match ( ttype , values , regex=False )


检查标记是否与给定参数匹配。

1e9e2149eca641308c75c520fca279bc.png

or运算为None匹配为True输出。


ttype是一种token类型。如果此标记与给定的标记类型不匹配。values是此标记的可能值列表。这些values一起进行OR运算,因此如果只有一个值与True匹配,则返回。除关键字标记外,比较区分大小写。为了方便起见,可以传入单个字符串。如果regex为True(默认值为False),则给定值将被视为正则表达式。


另外还有三种方法has_ancestor(other),is_child_of(other),within(group_cls)这都有调用功能函数相关,可以先不用了解。


由此Token传入流单体已经差不多分析完,但是AST树该如何生成这是个问题,还有关于树的递归问题和层级问题,我们继续根据基类来慢慢摸清。这篇文章已经足够多内容了,先打住。下一篇再细讲。

(linux-x86-ARM)麒麟V10安装DBeaver21.3通用的数据库管理工具和 SQL 客户端
记(linux-x86-ARM)麒麟V10安装DBeaver21.3通用的数据库管理工具和 SQL 客户端
10款优秀的SQL Server服务器监控工具
服务器是网络中最重要的资源之一,SQL Server的广泛普及使SQL Server监控工具成为长期网络维护的先决条件。使用服务器监控工具跟踪服务器的运行状况可以为你提供解决性能问题所需的信息。
几个必须掌握的SQL优化技巧(四):使用Trace工具分析优化器执行计划
在应用的开发过程中,由于开发初期的数据量一般都比较小,所以开发过程中一般都比较注重功能上的实现,但是当完成了一个应用或者系统之后,随着生产数据量的急剧增长,那么之前的很多sql语句的写法就会显现出一定的性能问题,对生产的影响也会越来越大,这些不恰当的sql语句就会成为整个系统性能的瓶颈,为了追求系统的极致性能,必须要对它们进行优化。