Python:两个解析语句无法协同工作

时间:2019-07-05 07:21:52

标签: python parsing pyparsing

在sql中,列名与表一起给出,即它们属于;以这种方式emp.ename或只是列名ename。 我正在编写一个使用PyParsing库解析此类sql语句的程序。 rc1是不带表名约定的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  }'}

第3个输入:(这里我结合了两个约定,即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 }'} 第四个:{'columns': 'ename lname ','tab': 'emp', 'Source_Columns': 'eid',from': '{database: scott table: employee }'}

我想念什么? (可以使用select_core.runTests(tests)查看输出,并且可以在tests中将输入作为字符串给出)

1 个答案:

答案 0 :(得分:1)

这是您为runTests设计的测试:

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中,这些实际上不应该是两个不同的语句,您应该只能编写一个捕获可选的主表名并为其指定适当结果名称的语句。然后将列名称分组,以便可以从每个列中提取名称和表。