Python 如何使用select_parser.py from pyparsing从SQL中获取表名?
当我使用pyparsing 2.2.0运行它时,使用以下代码:Python 如何使用select_parser.py from pyparsing从SQL中获取表名?,python,pyparsing,Python,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) 我明白了 尽管原始定义中有一
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)
我明白了
尽管原始定义中有一个命名元素“table”:
single_source = ( (Group(database_name("database") + "." + table_name("table*")) | table_name("table*")) +
没有名称为“table”的dict键
也许“from”元素首先消耗了一些东西?我不理解命名元素是如何填充的确切逻辑,我也没有从阅读文档(几次谈话等)中得到一个清晰的概念
如何使用select_parser.py获取SQL查询中的所有表名
注意:这里的正确答案是一个列表(或集合):test_table、test2_table、foo
我可以浏览“from”和抛弃列表,但这似乎有点粗糙,我不知道它是否会起作用,而且pyparsing似乎也不应该起作用
我明白了,但是我不明白它们在这里有什么帮助。您链接到的示例代码包括对
运行测试的调用。这是一个很好的工具,可以尝试不同的测试字符串,并为解析器编写单元测试
在调用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']
“表”名称在那里,但您必须对结构进行一些导航才能找到它们。这里有一个方法:
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']
对于解析数据的未来列表,请使用parserelation.runTests
和ParseResults.dump
方法。谢谢!我看到了runTests和dump及其输出,但1)我不知道struct.table格式,2)我不知道遍历树的范例。可以使用result[“name”]
dict键表示法或result.name
对象属性表示法访问命名结果字段(如果名称不存在,dict表示法将引发KeyError,而属性表示法将返回“”)。在线文档中的更多信息:。至于遍历树,这只是遍历从parseString
返回的嵌套解析数据。由于子表达式包装在pyparsingGroup
s中,因此您在解析结果中获得子结构。
['test_table', 'test2_table', 'foo']