Python 解析 SQL 并查找关系
Python parse SQL and find relationships
我有一大堆 SQL 查询都是字符串形式的,它们是为 Presto 编写的,所以有点格式化为 MySQL。
我希望能够梳理出某些查询中写入的 table 关系。
让我们从简单的事情开始:
SELECT e.object_id, count(*)
FROM schema_name.elements AS e
JOIN schema_name2.quotes AS q ON q.id = e.object_id
WHERE e.object_type = 'something'
GROUP BY e.object_id, q.query
ORDER BY 2 desc;
虽然有别名,但可以清楚地看到事物在何处连接在一起 - 因此需要扫描并找到别名 - 这很好,因为使用了关键字 "AS"。
所以我想为查询返回一个关系列表,每个关系看起来像这个字典:
dict = {'SourceSchema': 'schema_name',
'SourceTable': "elements",
'SourceColumn': "object_id",
'TargetSchema': "schema_name2",
'TargetTable': "quotes",
'TargetColumn': "id"}
我可以想象这样做很容易,但事情变得更加复杂:
SELECT e.object_id, count(*)
FROM schema_name.elements e
LEFT JOIN schema_name2.quotes q ON q.id = cast(coalesce(nullif(e.object_id,''),'0') as bigint)
WHERE e.object_type = 'something'
GROUP BY e.object_id, q.query
ORDER BY 2 desc;
3个注意事项
- 缺少 "AS" 保留字 - 可能更难获得
- 加入时,需要很多东西才能将两个 table 一起解析
- 这不是一个简单的"JOIN"它是一个左连接
我想知道是否有某种形式的 SQL Python 解析库可以让我梳理出大约 4000 个查询中的关系?如果没有,那我怎么能有效地做到这一点?我猜我可能需要扫描查询,找到连接,找到别名,然后查看它们是如何连接的,同时考虑到一堆需要丢弃的停用词。
对作为 pyparsing 示例一部分的 select_parser.py (https://sourceforge.net/p/pyparsing/code/HEAD/tree/trunk/src/examples/select_parser.py) 进行了一些小的更改,我在解析您的第一个示例后得到了这个:
SELECT e.object_id, count(*) FROM schema_name.elements AS e JOIN schema_name2.quotes AS q ON q.id = e.object_id WHERE e.object_type = 'something' GROUP BY e.object_id, q.query ORDER BY 2 desc;
['SELECT', [['e.object_id'], ['count', '*']], 'FROM', [['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]], 'WHERE', ['e.object_type', '=', 'something'], 'GROUP', 'BY', [['e.object_id'], ['q.query']], 'ORDER', 'BY', [['2', 'DESC']], ';']
- columns: [['e.object_id'], ['count', '*']]
[0]:
['e.object_id']
[1]:
['count', '*']
- from: [[['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]]]
[0]:
[['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]]
- table_alias: [['e'], ['q']]
[0]:
['e']
[1]:
['q']
- order_by_terms: [['2', 'DESC']]
[0]:
['2', 'DESC']
- direction: DESC
- order_key: 2
- where_expr: ['e.object_type', '=', 'something']
看来这个示例可能会帮助您入门。它被写入 SQLite 的 SELECT 格式,因此您需要扩展一些语法。
我有一大堆 SQL 查询都是字符串形式的,它们是为 Presto 编写的,所以有点格式化为 MySQL。
我希望能够梳理出某些查询中写入的 table 关系。
让我们从简单的事情开始:
SELECT e.object_id, count(*)
FROM schema_name.elements AS e
JOIN schema_name2.quotes AS q ON q.id = e.object_id
WHERE e.object_type = 'something'
GROUP BY e.object_id, q.query
ORDER BY 2 desc;
虽然有别名,但可以清楚地看到事物在何处连接在一起 - 因此需要扫描并找到别名 - 这很好,因为使用了关键字 "AS"。
所以我想为查询返回一个关系列表,每个关系看起来像这个字典:
dict = {'SourceSchema': 'schema_name',
'SourceTable': "elements",
'SourceColumn': "object_id",
'TargetSchema': "schema_name2",
'TargetTable': "quotes",
'TargetColumn': "id"}
我可以想象这样做很容易,但事情变得更加复杂:
SELECT e.object_id, count(*)
FROM schema_name.elements e
LEFT JOIN schema_name2.quotes q ON q.id = cast(coalesce(nullif(e.object_id,''),'0') as bigint)
WHERE e.object_type = 'something'
GROUP BY e.object_id, q.query
ORDER BY 2 desc;
3个注意事项
- 缺少 "AS" 保留字 - 可能更难获得
- 加入时,需要很多东西才能将两个 table 一起解析
- 这不是一个简单的"JOIN"它是一个左连接
我想知道是否有某种形式的 SQL Python 解析库可以让我梳理出大约 4000 个查询中的关系?如果没有,那我怎么能有效地做到这一点?我猜我可能需要扫描查询,找到连接,找到别名,然后查看它们是如何连接的,同时考虑到一堆需要丢弃的停用词。
对作为 pyparsing 示例一部分的 select_parser.py (https://sourceforge.net/p/pyparsing/code/HEAD/tree/trunk/src/examples/select_parser.py) 进行了一些小的更改,我在解析您的第一个示例后得到了这个:
SELECT e.object_id, count(*) FROM schema_name.elements AS e JOIN schema_name2.quotes AS q ON q.id = e.object_id WHERE e.object_type = 'something' GROUP BY e.object_id, q.query ORDER BY 2 desc;
['SELECT', [['e.object_id'], ['count', '*']], 'FROM', [['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]], 'WHERE', ['e.object_type', '=', 'something'], 'GROUP', 'BY', [['e.object_id'], ['q.query']], 'ORDER', 'BY', [['2', 'DESC']], ';']
- columns: [['e.object_id'], ['count', '*']]
[0]:
['e.object_id']
[1]:
['count', '*']
- from: [[['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]]]
[0]:
[['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]]
- table_alias: [['e'], ['q']]
[0]:
['e']
[1]:
['q']
- order_by_terms: [['2', 'DESC']]
[0]:
['2', 'DESC']
- direction: DESC
- order_key: 2
- where_expr: ['e.object_type', '=', 'something']
看来这个示例可能会帮助您入门。它被写入 SQLite 的 SELECT 格式,因此您需要扩展一些语法。