metasequoia-sql 是一款注重性能的 SQL 语法的解析和分析器,适用于 SQL 的格式化、执行和分析场景,致力于打造性能最高的 Python 版 SQL 解析器。
Project description
metasequoia-sql
metasequoia-sql 是一款注重性能的 SQL 语法的解析和分析器,适用于 SQL 的格式化、执行和分析场景,致力于打造性能最高的 Python 版 SQL 解析器。具有如下 3 个主要特性:
- 词法解析器与语法解析器相互独立,支持插件开发
- 使用单一状态机实现词法解析,避免大量正则表达式的复杂逻辑
- 除包含并列关系的节点外(例如
ORDER BY
多个字段),抽象语法树为完全的、根据计算优先级嵌套的一元和二元表达式结构
metasequoia-sql 包含词法树解析(lexical
模块)、语法树解析(core
模块)和语法树分析(analyzer
模块)等主要功能。
自 0.6.0 版本起,metasequoia-sql 的 public 方法 API 将尽可能支持向前兼容。
安装方法
pip install metasequoia-sql
使用方法
词法解析
单纯的词法解析,可以应用于 SQL 语句格式化等场景。
将 SQL 语句解析为一个词法节点的列表(demo_101),节点中包含对应的源代码(source
属性)以及节点标签(marks
属性)。
from metasequoia_sql import FSMMachine
amt_tree = FSMMachine.parse("SELECT column1, '2' FROM table_1")
for node in amt_tree:
print(node)
对于有括号的 SQL 语句,会将括号生成一个 AMTParenthesis
类型节点,该节点包含一个 PARENTHESIS
标记,括号中的词法节点会被添加到括号节点的 children
属性中(demo_102)。
from metasequoia_sql import FSMMachine
amt_tree = FSMMachine.parse("SELECT column1, (column2 + 1) * 2 FROM table_1")
for node in amt_tree:
print(node)
语法解析
将 SQL 语句解析为一个抽象语法树,返回抽象语法树的根节点。
词法解析支持一次性解析一个语句(demo_201):
from metasequoia_sql import SQLParser
statement = SQLParser.parse_select_statement("SELECT column1, '2' FROM table_1")
print(statement)
也支持一次性解析多个语句(demo_202):
from metasequoia_sql import SQLParser
statements = SQLParser.parse_statements("SELECT column1 FROM table_1; SELECT column2 FROM table_2")
for statement in statements:
print(statement)
此外,也可以解析语句中的某个部分(demo_203):
from metasequoia_sql import SQLParser
expression = SQLParser.parse_logical_and_level_expression("(`column1` > 2) AND (`column2` > 1)")
print(expression)
应用样例:数据血缘分析
通过基于语法解析器的数据血缘分析工具,可以实现对 SQL 语句的分析。例如:
分析 INSERT 语句的数据血缘。数据血缘分析需要依赖元数据,所以需要根据你的数据源继承 CreateTableStatementGetter
类并提供给数据血缘分析器(demo_301):
from metasequoia_sql import *
from metasequoia_sql.analyzer import CreateTableStatementGetter
from metasequoia_sql.analyzer.data_linage.table_lineage_analyzer import TableLineageAnalyzer
table_lineage_analyzer = TableLineageAnalyzer(CreateTableStatementGetter(...))
for statement in SQLParser.parse_statements("your sql file"):
if isinstance(statement, ASTInsertSelectStatement):
result = table_lineage_analyzer.get_insert_table_lineage(statement)
插件样例:MyBatis 插件(暂未完善)
通过重写了语法解析器和词法解析器的插件,可以实现对特殊 SQL 语法的解析。例如:
对 MyBatis 语法进行解析(demo_302):
from metasequoia_sql.plugins.mybaitis import SQLParserMyBatis
statements = SQLParserMyBatis.parse_statements("SELECT column_1 FROM Shohin "
"WHERE #{column_2} > 500 "
"GROUP BY #{column_3}")
for statement in statements:
print(statement)
工具样例:SQL on OTS(暂未发布)
通过基于语法解析器的工具,可以实现一些实现 SQL 执行的工具。
性能比较
- 测试样本:4482 个脚本,共 19880057 字节(18.96 MB)的 SQL 语句。
- 测试 Python环境:Python 3.10
- 测试 CPU:Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
解析时间 | 平均解析速度 | |
---|---|---|
metasequoia-sql | 65.28 秒 | 297.4 KB / s |
sqlglot | 182.74 秒 | 106.2 KB / s |
基本特性
- 词法解析器与句法解析器分离
- 使用单一、独立的状态机实现词法解析
- 除了逻辑并列的场景外,抽象语法树为完全的嵌套二元表达式
参与贡献
单元测试当前不会自动检查):
运行 scripts/test/test_main.py
脚本。如果有新增功能,也需要新增对应的单元测试。
pylint 代码质量检查(在 Pull Request 时自动检查):
pylint --max-line-length=120 metasequoia_sql
单元测试覆盖率检查(当前不会自动检查):
# 将 metasequoia-sql 文件夹添加到 PYTHONPATH,并在 metasequoia-sql 文件夹下执行
coverage run .\scripts\tests\test_main.py
coverage report # 生成文字报告
coverage html # 生成 HTML 报告
版本更新记录
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file metasequoia-sql-0.6.0.tar.gz
.
File metadata
- Download URL: metasequoia-sql-0.6.0.tar.gz
- Upload date:
- Size: 62.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.11.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 56196fe6b5631c3bc6bf4af6ed555daabc2996c1083242b7176dec1548a6b2f2 |
|
MD5 | 146d112f54191521e936e02f32914f67 |
|
BLAKE2b-256 | bf1c1281413ebc49cac7b896f0720077f2e3ab01b7b8444f492bf3f16bd9c2bd |