2016-09-13 5 views
1

У меня есть большой список SQL-запросов в строках, они написаны для Presto, поэтому отформатированы для MySQL.Python parse SQL и найти отношения

Я хочу быть в состоянии дразнить отношения таблицы, написанные в некоторых запросах.

Давайте начнем с чего-нибудь простого:

SELECT e.object_id, count(*) 
FROM schema_name.elements AS e 
     JOIN schema_name2.quotes AS q ON q.id = e.object_id 
WHERE e.object_type = 'something' 
GROUP BY e.object_id, q.query 
ORDER BY 2 desc; 

Можно четко видеть, где все объединятся, хотя есть псевдонимы - так должен был бы просканировать и найти псевдонимы тоже - это прекрасно, как ключевое слово «AS» является используемый.

Так что я бы хотел, чтобы вернули список отношений для запроса, каждое отношение будет выглядеть примерно так: Dict

dict = {'SourceSchema': 'schema_name', 
'SourceTable': "elements", 
'SourceColumn': "object_id", 
'TargetSchema': "schema_name2", 
'TargetTable': "quotes", 
'TargetColumn': "id"} 

Я могу себе представить, что делает это довольно просто, но материал становится все более сложная:

SELECT e.object_id, count(*) 
FROM schema_name.elements e 
     LEFT JOIN schema_name2.quotes q ON q.id = cast(coalesce(nullif(e.object_id,''),'0') as bigint) 
WHERE e.object_type = 'something' 
GROUP BY e.object_id, q.query 
ORDER BY 2 desc; 

3 вещи, чтобы отметить

  • Missing "AS" зарезервированное слово - может это сделать труднее получить
  • При соединении, есть много вещей нужно разобрать две таблицы вместе
  • Это не просто «JOIN» это левая присоединиться

мне интересно, если есть какая-то форма библиотеки SQL Parsing для Python, которая позволит мне дразнить отношения в некоторых 4000 запросах? А если нет, то как я могу сделать это эффективно? Я предполагаю, что мне, возможно, понадобится сканировать запросы, найти соединения, найти псевдоним, а затем посмотреть, как они объединены, принимая во внимание кучу слов остановки, которые нужно отбросить.

ответ

1

С некоторыми незначительными изменениями в select_parser.py (https://sourceforge.net/p/pyparsing/code/HEAD/tree/trunk/src/examples/select_parser.py), которая является частью примеров Pyparsing, я получаю это после разбора вашего первого примера:

SELECT e.object_id, count(*) FROM schema_name.elements AS e  JOIN schema_name2.quotes AS q ON q.id = e.object_id WHERE e.object_type = 'something' GROUP BY e.object_id, q.query ORDER BY 2 desc; 
['SELECT', [['e.object_id'], ['count', '*']], 'FROM', [['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]], 'WHERE', ['e.object_type', '=', 'something'], 'GROUP', 'BY', [['e.object_id'], ['q.query']], 'ORDER', 'BY', [['2', 'DESC']], ';'] 
- columns: [['e.object_id'], ['count', '*']] 
    [0]: 
    ['e.object_id'] 
    [1]: 
    ['count', '*'] 
- from: [[['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]]] 
    [0]: 
    [['schema_name', '.', 'elements'], 'AS', 'e', ['JOIN'], ['schema_name2', '.', 'quotes'], 'AS', 'q', ['ON', ['q.id', '=', 'e.object_id']]] 
    - table_alias: [['e'], ['q']] 
     [0]: 
     ['e'] 
     [1]: 
     ['q'] 
- order_by_terms: [['2', 'DESC']] 
    [0]: 
    ['2', 'DESC'] 
    - direction: DESC 
    - order_key: 2 
- where_expr: ['e.object_type', '=', 'something'] 

Так выглядит этот пример может помочь вам получить начал. Он был записан в формат SELECT для SQLite, поэтому вам нужно будет расширить часть синтаксиса.

+0

Благодарим за отзыв! Да, я думаю, что получить пирап, чтобы сделать это для меня, было бы самым простым способом. Я просмотрел и нашел это после публикации: http://pyparsing.wikispaces.com/file/view/select_parser.py/158651233/select_parser.py – edumike