.ts
1
Anaconda
1
centos7
2
eclipse
2
FileBird
1
graphviz
1
hadoop
2
HDFS
1
IDEA
2
java
8
JavaScript
3
jdk
1
JetBrains
1
jupyter
1
Linux
3
LPL
1
m3u8
1
mapreduce
1
maven
2
MongoDB
9
mp4
1
MySQL
6
Navicat
3
NoSQL
1
PIL
1
Pycharm
1
Python
25
RGB
1
Robo-3T
1
selenium
0
smtp
1
SpringBoot
1
Tomcat
1
Windows
1
WordPress
11
wpmail
1
二叉树
1
信息系统开发
1
免费
1
全家桶
1
冒泡排序
1
分类预测
1
压缩包
1
哈夫曼
1
图片处理
1
增、删、改、查
0
媒体库
1
学生认证
1
安装
4
宝塔
2
建模
1
插件
4
操作
1
数据分析
1
数据变换
1
数据库
1
数据挖掘
2
数据类型
1
数据结构
1
文件
1
文档更新
1
概述
2
爬虫
2
环境变量
1
线程
1
统计
1
网站
1
网站统计
2
自动
1
连接navicat
1
面板
0
音乐播放器
1
本文最后更新于 144 天前,其中的信息可能已经有所发展或是发生改变。
一、sqlparse简介
首先先给官网地址:python-sqlparse。有足够好编码能力可以直接上github上面看源码,解读更细:github.sqlparse
sqlparse是用于Python的非验证SQL解析器。它支持解析、拆分和格式化SQL语句。既然有解析功能那么我们就能做初步的血缘解析功能。这个库的函数解析没有像Pandas和numpy写的那么详细,毕竟是人家个人的开源库,功能写的已经很不错了,能够省去我们很多递归剥离AST树的时间。官网上关于该库使用操作很简单,很多比较好的功能函数也没有使用到,我希望可以尽力将此库开发为通用SQL血缘解析的基础工具库。如果该功能开发完我会将此项目开源。
我通过细读源码来了解此库的大体功能。
二、功能代码解析
看初始化代码方法有四种:parse,parsestream,format,split这四种
1.初始方法
1.parse
def parse(sql, encoding=None):
"""Parse sql and return a list of statements.
:param sql: A string containing one or more SQL statements.
:param encoding: The encoding of the statement (optional).
:returns: A tuple of :class:`~sqlparse.sql.Statement` instances.
return tuple(parsestream(sql, encoding))
传入一个SQL语句,返回一个 sqlparse.sql.Statement的元组,我们可以递归方式获得输出
query = 'Select a, col_2 as b from Table_A;'
for each in sqlparse.parse(query):
print(each)
其元组根据;符号来进行切分存储
query = 'Select a, col_2 as b from Table_A;select * from foo'
for each in sqlparse.parse(query):
print(each)
select a, col_2 as b from Table_A;
select * from foo
2.parsestream
可以看到第一个方法是调用了parsestream来完成流式解析的,那么这个方法也就是循环读取sql语句来完成转换statment的:
def parsestream(stream, encoding=None):
"""Parses sql statements from file-like object.
:param stream: A file-like object.
:param encoding: The encoding of the stream contents (optional).
:returns: A generator of :class:`~sqlparse.sql.Statement` instances.
stack = engine.FilterStack()
stack.enable_grouping()
return stack.run(stream, encoding)
这里的引擎是可以替换的。
sqlparse.parsestream(query)
它将返回一个sqlparse.sql.Statement实例的发生器。来看看这个run方法:
def run(self, sql, encoding=None):
stream = lexer.tokenize(sql, encoding)
# Process token stream
for filter_ in self.preprocess:
stream = filter_.process(stream)
stream = StatementSplitter().process(stream)
# Output: Stream processed Statements
for stmt in stream:
if self._grouping:
stmt = grouping.group(stmt)
for filter_ in self.stmtprocess:
filter_.process(stmt)
for filter_ in self.postprocess:
stmt = filter_.process(stmt)
yield stmt
该方法就是生产一个statment,这个类应该就是这个库的基类了,多半围绕这个数据结构来处理。
该方法就是将sql语句标准化:
query = 'Select a, col_2 as b from Table_A;select * from foo'
print(sqlparse.format(query, reindent=True, keyword_case='upper'))
select a, col_2 as b from Table_A;
select * from foo
format()函数接受关键字参数:
keyword_case 关键词upper、lowersql的保留字大小写
identifier_case 标识符的upper、lower大小写
strip_comments=Ture删除注释
reindent=Ture美化sq缩进语句发生改变
format()函数接受关键字参数:
keyword_case 关键词upper、lowersql的保留字大小写
identifier_case 标识符的upper、lower大小写
strip_comments=Ture删除注释
reindent=Ture美化sq缩进语句发生改变
4.split
该方法用于分割sql语句:
sqlparse.split(query)
select a, col_2 as b from Table_A;
select * from foo
这里补充一下calss类sqlparse.sql.Statement是可以直接通过str转换为字符串的。
结果返回一个分割后的list。至此初始方法就写完了,下面我将详解一下基类,这将决定是我们是否能灵活运用此库。
2.基类-Token
我们来看看Token的初始方法属性:
def __init__(self, ttype, value):
value = str(value)
self.value = value
self.ttype = ttype
self.parent = None
self.is_group = False
self.is_keyword = ttype in T.Keyword
self.is_whitespace = self.ttype in T.Whitespace
self.normalized = value.upper() if self.is_keyword else value
这个Token类也就是语法解析器的重点数据流了:
此类需要生成Tokens使用,这牵扯到另一个方法
tokens.py
:
此方法也就是将statment类转换为Token流:
parsed = sqlparse.parse(query)
stmt = parsed[0]
stmt.tokens
其中我们需要解析的每个Token的标识码也就是第一个ttype属性,解析之后:
for each_token in sql_tokens:
print(each_token.ttype,each_token.value)
我们拿一个Token来研究就能逐渐解析到其他token。我们建立一个列表将其主要属性ttype和value收集起来:
type(list_ttype[0])
type(list_value[0])
第一个属性为sqlparse.tokens._TokenType第二个value直接就是str了。上tokens看_TokenType:
# Special token types
Text = Token.Text
Whitespace = Text.Whitespace
Newline = Whitespace.Newline
Error = Token.Error
# Text that doesn't belong to this lexer (e.g. HTML in PHP)
Other = Token.Other
# Common token types for source code
Keyword = Token.Keyword
Name = Token.Name
Literal = Token.Literal
String = Literal.String
Number = Literal.Number
Punctuation = Token.Punctuation
Operator = Token.Operator
Comparison = Operator.Comparison
Wildcard = Token.Wildcard
Comment = Token.Comment
Assignment = Token.Assignment
# Generic types for non-source code
Generic = Token.Generic
Command = Generic.Command
# String and some others are not direct children of Token.
# alias them:
Token.Token = Token
Token.String = String
Token.Number = Number
# SQL specific tokens
DML = Keyword.DML
DDL = Keyword.DDL
CTE = Keyword.CTE
可以发现这就是Token的识别解析类型码,通过该码就可以访问获得解析出的关键字了。
关于此基类又有五种主要的方法:
用于解析子组
for each_token in sql_tokens:
#list_ttype.append(each_token.ttype),list_value.append(each_token.value)
print(each_token.flatten())
2.
match
(
ttype
,
values
,
regex=False
)
检查标记是否与给定参数匹配。
list_ttype=[]
list_value=[]
for each_token in sql_tokens:
#list_ttype.append(each_token.ttype),list_value.append(each_token.value)
print(each_token.match(each_token.ttype,each_token.ttype))
or运算为None匹配为True输出。
ttype是一种token类型。如果此标记与给定的标记类型不匹配。values是此标记的可能值列表。这些values一起进行OR运算,因此如果只有一个值与True匹配,则返回。除关键字标记外,比较区分大小写。为了方便起见,可以传入单个字符串。如果regex为True(默认值为False),则给定值将被视为正则表达式。
另外还有三种方法has_ancestor(other),is_child_of(other),within(group_cls)这都有调用功能函数相关,可以先不用了解。
由此Token传入流单体已经差不多分析完。
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
jupyter notebook报错failed to execute ‘dot’, make sure the Graphviz executables are on your systems
PyCharm安装教程(简单又实用)
LPL数据分析(2020-2022赛季)
Python暴力破解压缩包密码
python通过scapy模块进行arp断网攻击
Anaconda超详细安装教程(Windows环境下)
Python图形处理
【python图像处理】几何图形的绘制与文字的绘制(ImageDraw类详解)及Image.save设置