Python: два оператора разбора не работают вместе - PullRequest
0 голосов
/ 05 июля 2019

В именах столбцов sql указывается вместе с таблицей, к которой они относятся, т.е.таким образом - emp.ename или просто имя столбца ename.Я пишу программу для анализа этих SQL-операторов с использованием библиотеки PyParsing.rc1 - это соглашение об отсутствии имени таблицы, а 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  }'}

2-й ввод:

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'}

Я надеюсь, вы понимаете мою проблему из этих входов / выходов 3-й выход долженбыло что-то вроде этого: {'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)

1 Ответ

1 голос
/ 06 июля 2019

Вот ваши тесты, выложенные для 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 вы должны быть способны написать только одно, которое захватывает необязательное имя ведущей таблицы, и дать ему соответствующее имя результата.Затем сделайте имя столбца группой, чтобы из каждого можно было извлечь имя и таблицу.

...