Подтвердить что ты не робот

Разбор SQL с Python

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

Я изучаю использование ANTLR для создания AST, представляющего SQL как выражение реляционной алгебры. Затем возвращайте данные, оценивая/ходя по дереву.

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

  • Описывается ли описанный выше подход правильно?
  • Есть ли другие инструменты/библиотеки, на которые я должен смотреть? Как PLY или Pyparsing.
  • Приветствуются указатели на статьи, книги или исходный код, которые помогут мне.

Update:

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 3

TwoLaid Python SQL Parser отлично работает для моих целей. Он написан на 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']

Ответ 4

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

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