如何使用来自 pyparsing 的 select_parser.py 从 SQL 获取 table 名称?
How to get table names from SQL using select_parser.py from pyparsing?
当我使用此代码将 select_parser.py from pyparsing 和 运行 与 pyparsing 2.2.0 一起使用时:
query="select z.a, b from test_table left join test2_table where 1=1 and b in (select bb from foo)"
for key, val in select_stmt.parseString(query, parseAll=True).items():
print "%s: %s" % (key, val)
我明白了
$ python select_parser.pyparsing.py
where_expr: [['1', '=', '1'], 'AND', ['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]]
from: [['test_table', ['LEFT', 'JOIN'], 'test2_table', []]]
columns: [['z.a'], ['b']]
虽然原定义中有命名元素"table":
single_source = ( (Group(database_name("database") + "." + table_name("table*")) | table_name("table*")) +
没有以名称 "table" 出现的字典键。
也许 "from" 元素首先消耗了东西?我不明白命名元素如何填充的确切逻辑,而且我没有通过阅读文档(几次谈话等)得到一个清晰的想法。
如何使用 select_parser.py 获取 SQL 查询中的所有 table 名称?
注意:这里的正确答案是一个列表(或集合):test_table, test2_table, foo.
我可以浏览 "from" 和沟槽列表,但这看起来很老套,我不知道它是否可行,而且 pyparsing 似乎不应该如何工作。
我看到了 this question, this one, and this one,但我不明白他们是如何提供帮助的。
您链接到的示例代码包括对 runTests
的调用。这是一个很棒的工具,可以用来尝试不同的测试字符串,并为您的解析器编写单元测试。
在对 runTests
的调用中插入您的查询字符串时,我们得到以下输出:
select z.a, b from test_table left join test2_table where 1=1 and b in (select bb from foo)
['SELECT', [['z.a'], ['b']], 'FROM', ['test_table', ['LEFT', 'JOIN'], 'test2_table', []], 'WHERE', [['1', '=', '1'], 'AND', ['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]]]
- columns: [['z.a'], ['b']]
[0]:
['z.a']
[1]:
['b']
- from: [['test_table', ['LEFT', 'JOIN'], 'test2_table', []]]
[0]:
['test_table', ['LEFT', 'JOIN'], 'test2_table', []]
- table: [['test_table'], ['test2_table']]
[0]:
['test_table']
[1]:
['test2_table']
- where_expr: [['1', '=', '1'], 'AND', ['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]]
[0]:
['1', '=', '1']
[1]:
AND
[2]:
['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]
[0]:
b
[1]:
IN
[2]:
['SELECT', [['bb']], 'FROM', 'foo']
- columns: [['bb']]
[0]:
['bb']
- from: ['foo']
- table: [['foo']]
[0]:
['foo']
'table' 名称 在那里,但您必须对结构进行一些导航才能找到它们。这是一种方法:
result = select_stmt.parseString(query)
table_names = []
def visit_structure(struct):
if 'table' in struct:
table_names.extend(t[0] for t in struct.table)
for substruct in struct:
if isinstance(substruct, ParseResults):
visit_structure(substruct)
visit_structure(result)
print(table_names)
给出:
['test_table', 'test2_table', 'foo']
为了将来列出已解析的数据,请使用 ParserElement.runTests
和 ParseResults.dump
方法。
当我使用此代码将 select_parser.py from pyparsing 和 运行 与 pyparsing 2.2.0 一起使用时:
query="select z.a, b from test_table left join test2_table where 1=1 and b in (select bb from foo)"
for key, val in select_stmt.parseString(query, parseAll=True).items():
print "%s: %s" % (key, val)
我明白了
$ python select_parser.pyparsing.py
where_expr: [['1', '=', '1'], 'AND', ['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]]
from: [['test_table', ['LEFT', 'JOIN'], 'test2_table', []]]
columns: [['z.a'], ['b']]
虽然原定义中有命名元素"table":
single_source = ( (Group(database_name("database") + "." + table_name("table*")) | table_name("table*")) +
没有以名称 "table" 出现的字典键。
也许 "from" 元素首先消耗了东西?我不明白命名元素如何填充的确切逻辑,而且我没有通过阅读文档(几次谈话等)得到一个清晰的想法。
如何使用 select_parser.py 获取 SQL 查询中的所有 table 名称?
注意:这里的正确答案是一个列表(或集合):test_table, test2_table, foo.
我可以浏览 "from" 和沟槽列表,但这看起来很老套,我不知道它是否可行,而且 pyparsing 似乎不应该如何工作。
我看到了 this question, this one, and this one,但我不明白他们是如何提供帮助的。
您链接到的示例代码包括对 runTests
的调用。这是一个很棒的工具,可以用来尝试不同的测试字符串,并为您的解析器编写单元测试。
在对 runTests
的调用中插入您的查询字符串时,我们得到以下输出:
select z.a, b from test_table left join test2_table where 1=1 and b in (select bb from foo)
['SELECT', [['z.a'], ['b']], 'FROM', ['test_table', ['LEFT', 'JOIN'], 'test2_table', []], 'WHERE', [['1', '=', '1'], 'AND', ['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]]]
- columns: [['z.a'], ['b']]
[0]:
['z.a']
[1]:
['b']
- from: [['test_table', ['LEFT', 'JOIN'], 'test2_table', []]]
[0]:
['test_table', ['LEFT', 'JOIN'], 'test2_table', []]
- table: [['test_table'], ['test2_table']]
[0]:
['test_table']
[1]:
['test2_table']
- where_expr: [['1', '=', '1'], 'AND', ['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]]
[0]:
['1', '=', '1']
[1]:
AND
[2]:
['b', 'IN', ['SELECT', [['bb']], 'FROM', 'foo']]
[0]:
b
[1]:
IN
[2]:
['SELECT', [['bb']], 'FROM', 'foo']
- columns: [['bb']]
[0]:
['bb']
- from: ['foo']
- table: [['foo']]
[0]:
['foo']
'table' 名称 在那里,但您必须对结构进行一些导航才能找到它们。这是一种方法:
result = select_stmt.parseString(query)
table_names = []
def visit_structure(struct):
if 'table' in struct:
table_names.extend(t[0] for t in struct.table)
for substruct in struct:
if isinstance(substruct, ParseResults):
visit_structure(substruct)
visit_structure(result)
print(table_names)
给出:
['test_table', 'test2_table', 'foo']
为了将来列出已解析的数据,请使用 ParserElement.runTests
和 ParseResults.dump
方法。