Вопрос

Я хочу создать интерфейс SQL поверх нереляционного хранилища данных.Нереляционное хранилище данных, но имеет смысл обращаться к данным реляционным способом.

Я рассматриваю возможность использования АНТЛР для создания AST, который представляет SQL как выражение реляционной алгебры.Затем верните данные, оценивая/обходя дерево.

Я никогда раньше не реализовал парсер, и поэтому мне хотелось бы получить совет о том, как лучше всего реализовать синтаксический анализатор и оценщик SQL.

  • Подходит ли описанный выше подход?
  • Есть ли другие инструменты/библиотеки, на которые мне следует обратить внимание?Нравиться ПЛИ или Пипарсинг.
  • Указатели на статьи, книги или исходный код, которые могут мне помочь, приветствуются.

Обновлять:

Я реализовал простой парсер SQL, используя pyparsing.В сочетании с кодом Python, реализующим реляционные операции с моим хранилищем данных, это было довольно просто.

Как я сказал в одном из комментариев, цель упражнения заключалась в том, чтобы сделать данные доступными для систем отчетности.Для этого мне, вероятно, понадобится реализовать драйвер ODBC.Наверное, это большой труд.

Это было полезно?

Решение

Я довольно подробно изучил этот вопрос.Python-sqlparse — это парсер без проверки, который на самом деле не то, что вам нужно.Примеры в antlr требуют большой работы, чтобы преобразовать их в хороший ast в python.Стандартные программисты sql: здесь, но преобразование их самостоятельно потребовало бы полной занятости, и вполне вероятно, что вам понадобится только их подмножество, т. е. никаких объединений.Вы можете попробовать посмотреть овод (база данных Python sql), но я избегал этого, поскольку они использовали свой собственный инструмент синтаксического анализа.

В моем случае мне понадобилось только предложениеwhere.Я пытался буленео (анализатор логических выражений), написанный с использованием pyparsing, но в конечном итоге использующий pyparsing с нуля.Первая ссылка в сообщении Марка Рушакова на Reddit дает пример использования sql. Свист полнотекстовая поисковая система также использует его, но я не смотрел источник, чтобы узнать, как это сделать.

Pyparsing очень прост в использовании, и вы можете легко настроить его так, чтобы он не был точно таким же, как sql (большая часть синтаксиса вам не понадобится).Мне не понравился ply, поскольку в нем используется некоторая магия, связанная с соглашениями об именах.

Короче говоря, попробуйте pyparsing, он, скорее всего, будет достаточно мощным, чтобы делать то, что вам нужно, а простая интеграция с Python (с простыми обратными вызовами и обработкой ошибок) сделает работу довольно безболезненной.

Другие советы

Этот пост на Reddit предполагает Python-sqlparse как существующая реализация, среди пары других ссылок.

Python SQL Parser от TwoLaid очень хорошо подходит для моих целей.Он написан на C и требует компиляции.Он прочный.Он анализирует отдельные элементы каждого предложения.

https://github.com/TwoLaid/python-sqlparser

Я использую его для анализа имен столбцов запросов для использования в заголовках отчета.Вот пример.

import sqlparser

def get_query_columns(sql):
   '''Return a list of column headers from given sqls select clause'''

   columns = []

   parser = sqlparser.Parser()

   # Parser does not like new lines
   sql2 = sql.replace('\n', ' ')

   # Check for syntax errors
   if parser.check_syntax(sql2) != 0:
      raise Exception('get_query_columns: SQL invalid.')

   stmt = parser.get_statement(0)
   root = stmt.get_root()
   qcolumns = root.__dict__['resultColumnList']
   for qcolumn in qcolumns.list:
      if qcolumn.aliasClause:
         alias = qcolumn.aliasClause.get_text()
         columns.append(alias)
      else:
         name = qcolumn.get_text()
         name = name.split('.')[-1] # remove table alias
         columns.append(name)

   return columns

sql = '''
SELECT 
   a.a,
   replace(coalesce(a.b, 'x'), 'x', 'y') as jim,
   a.bla as sally  -- some comment
FROM
   table_a as a
WHERE
   c > 20
'''

print get_query_columns(sql)

# output: ['a', 'jim', 'sally']

Конечно, лучше всего использовать python-sqlparse в Google Code

ОБНОВЛЯТЬ:Теперь я вижу, что это было предложено - я согласен, что это того стоит:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top