python sql parsing pyparsing

Analizando SQL con Python



parsing pyparsing (4)

Quiero crear una interfaz SQL en la parte superior de un almacén de datos no relacionales. Almacén de datos no relacionales, pero tiene sentido acceder a los datos de una manera relacional.

Estoy buscando usar ANTLR para producir un AST que represente el SQL como una expresión de álgebra relacional. Luego regrese datos evaluando / caminando el árbol.

Nunca antes había implementado un analizador y, por lo tanto, me gustaría recibir algunos consejos sobre cómo implementar mejor un analizador y un evaluador de SQL.

  • ¿El enfoque descrito arriba suena correcto?
  • ¿Hay otras herramientas / bibliotecas que debería considerar? Como PLY o Pyparsing .
  • Apunta a los artículos, libros o código fuente que me ayudarán.

Actualizar:

Implementé un analizador simple de SQL usando pyparsing. Combinado con el código de Python que implementa las operaciones relacionales contra mi almacén de datos, esto fue bastante simple.

Como dije en uno de los comentarios, el objetivo del ejercicio era poner los datos a disposición de los motores de informes. Para hacer esto, probablemente necesite implementar un controlador ODBC. Esto es probablemente mucho trabajo.


El Analizador de Python SQL de TwoLaid funciona muy bien para mis propósitos. Está escrito en C y necesita ser compilado. Es robusto Analiza los elementos individuales de cada cláusula.

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

Lo estoy usando para analizar los nombres de las columnas de las consultas para usar en los encabezados de los informes. Aquí hay un ejemplo.

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


He investigado este tema bastante extensamente. Python-sqlparse es un analizador no validador que no es realmente lo que necesita. Los ejemplos en antlr necesitan mucho trabajo para convertirse en un buen ast en python. Las gramáticas estándares sql están here , pero sería un trabajo de tiempo completo convertirlas tú mismo y es probable que solo necesites un subconjunto de ellas, es decir, sin uniones. También podrías intentar mirar el gadfly (una base de datos python sql), pero lo evité ya que usaban su propia herramienta de análisis.

Para mi caso, esencialmente solo necesitaba una cláusula Where. booleneo (un analizador de expresiones booleanas) escrito con pyparsing pero terminé usando pyreared desde cero. El primer enlace en la publicación de reddit de Mark Rushakoff da un ejemplo sql usándolo. Whoosh un motor de búsqueda de texto completo también lo usa, pero no he buscado en la fuente para ver cómo.

Pyparsing es muy fácil de usar y puede personalizarlo fácilmente para que no sea exactamente igual a sql (la mayoría de la sintaxis no la necesitará). No me gustó porque usa magia usando las convenciones de nomenclatura.

En resumen, pruebe pyparsing, lo más probable es que sea lo suficientemente potente como para hacer lo que necesita y la integración simple con Python (con devoluciones de llamadas y manejo de errores) hará que la experiencia sea bastante sencilla.


Por supuesto, puede ser mejor aprovechar python-sqlparse en Google Code

ACTUALIZACIÓN: Ahora veo que esto ha sido sugerido. Estoy de acuerdo en que esto vale la pena: