Python 如何使用select_parser.py from pyparsing从SQL中获取表名?

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) 我明白了 尽管原始定义中有一

当我使用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)
我明白了

尽管原始定义中有一个命名元素“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
返回的嵌套解析数据。由于子表达式包装在pyparsing
Group
s中,因此您在解析结果中获得子结构。
['test_table', 'test2_table', 'foo']