Python: 两个解析语句不能一起工作

Python: Two parse statements not working together

在 sql 中,列名与 table 一起给出,即;以这种方式 - emp.ename 或只是列名 ename。 我正在编写一个程序来使用 PyParsing 库解析这些类型的 sql 语句。 rc1 是没有 table 名称约定的 for,rc2 是另一个。

rc1=delimitedList(column_name("columns*") + Optional(Optional(AS) + column_alias("col_alias*"))) + (ZeroOrMore(delimitedList(rc2)))

rc2= OneOrMore(delimitedList(("tab") + "." + column_name("Source_Columns") + Optional(Optional(AS) + column_alias)))

result_column = "*" | OneOrMore(delimitedList(table_name("tab") + "." + column_name("Source_Columns") + Optional(Optional(AS) + column_alias("col_alias"))))| OneOrMore(rc1) |OneOrMore(rc2)|OneOrMore(rc1+rc2)|OneOrMore(rc2+rc1)

select_core = (SELECT + Optional(DISTINCT | ALL) + OneOrMore(result_column) +
                Optional(FROM + join_source("from*")) 

在 result_column 中,两者都已读取。我给出了所有的组合 rc1+rc2, rc2+rc1.. 假设我的第一个输入查询是:

SELECT emp.ename as e FROM scott.employee as emp

输出为:

{'tab': 'emp', 'Source_Columns': 'ename', 'col_alias': 'e', 'table_alias': 'emp', 'from': '{database:  scott   table:   employee  }'}

第二个输入:

SELECT ename as e, fname as f FROM scott.employee as emp

输出:

{'columns': 'ename    fname', 'col_alias': 'e    f', 'table_alias': 'emp', 'from': '{database:  scott   table:   employee  }'}

第三个输入:(这里我结合了两个约定,即'rc2+rc1)

SELECT emp.eid, fname,lname FROM scott.employee as emp

输出:

{'tab': 'emp', 'Source_Columns': 'eid'}

第 4 个输入:(这里我结合了两个约定,即'rc1+rc2)

SELECT ename, lname, emp.eid FROM scott.employee as emp

输出:

{'columns': 'ename    lname    emp'}

我希望你能从这些中理解我的问题I/O 第三个输出应该是这样的:{'tab': 'emp', 'Source_Columns': 'eid', 'columns':'fname lname','from': '{database: scott table: employee }'} 第 4 个:{'columns': 'ename lname ','tab': 'emp', 'Source_Columns': 'eid',from': '{database: scott table: employee }'}

我错过了什么? (可以使用 select_core.runTests(tests) 查看输出,输入可以在 tests 中作为字符串给出)

以下是为运行测试安排的测试:

tests = """\
SELECT emp.ename as e FROM scott.employee as emp
SELECT ename as e, fname as f FROM scott.employee as emp
#Here I combine both conventions i.e' rc2+rc1)
SELECT emp.eid, fname,lname FROM scott.employee as emp
#Here I combine both conventions i.e' rc1+rc2)
SELECT ename, lname, emp.eid FROM scott.employee as emp
"""

使用 select_parser.py 中的解析器,runTests 输出为:

SELECT emp.ename as e FROM scott.employee as emp
['SELECT', [['emp.ename', 'AS', 'e']], 'FROM', ['scott', '.', 'employee'], 'AS', 'emp']
- columns: [['emp.ename', 'AS', 'e']]
  [0]:
    ['emp.ename', 'AS', 'e']
- from: [['scott', '.', 'employee']]
  [0]:
    ['scott', '.', 'employee']
    - database: ['scott']
    - table: [['employee']]
      [0]:
        ['employee']
- table_alias: [['emp']]
  [0]:
    ['emp']


SELECT ename as e, fname as f FROM scott.employee as emp
['SELECT', [['ename', 'AS', 'e'], ['fname', 'AS', 'f']], 'FROM', ['scott', '.', 'employee'], 'AS', 'emp']
- columns: [['ename', 'AS', 'e'], ['fname', 'AS', 'f']]
  [0]:
    ['ename', 'AS', 'e']
  [1]:
    ['fname', 'AS', 'f']
- from: [['scott', '.', 'employee']]
  [0]:
    ['scott', '.', 'employee']
    - database: ['scott']
    - table: [['employee']]
      [0]:
        ['employee']
- table_alias: [['emp']]
  [0]:
    ['emp']

#Here I combine both conventions i.e' rc2+rc1)
SELECT emp.eid, fname,lname FROM scott.employee as emp
['SELECT', [['emp.eid'], ['fname'], ['lname']], 'FROM', ['scott', '.', 'employee'], 'AS', 'emp']
- columns: [['emp.eid'], ['fname'], ['lname']]
  [0]:
    ['emp.eid']
  [1]:
    ['fname']
  [2]:
    ['lname']
- from: [['scott', '.', 'employee']]
  [0]:
    ['scott', '.', 'employee']
    - database: ['scott']
    - table: [['employee']]
      [0]:
        ['employee']
- table_alias: [['emp']]
  [0]:
    ['emp']

#Here I combine both conventions i.e' rc1+rc2)
SELECT ename, lname, emp.eid FROM scott.employee as emp
['SELECT', [['ename'], ['lname'], ['emp.eid']], 'FROM', ['scott', '.', 'employee'], 'AS', 'emp']
- columns: [['ename'], ['lname'], ['emp.eid']]
  [0]:
    ['ename']
  [1]:
    ['lname']
  [2]:
    ['emp.eid']
- from: [['scott', '.', 'employee']]
  [0]:
    ['scott', '.', 'employee']
    - database: ['scott']
    - table: [['employee']]
      [0]:
        ['employee']
- table_alias: [['emp']]
  [0]:
    ['emp']

在 pyparsing 中,这实际上不应该是两个不同的语句,您应该能够只编写一个捕获可选前导 table 名称的语句,并为其赋予适当的结果名称。然后把列名做成一个组,这样name和table就可以各自提取出来了。