2009-09-08 34 views
38

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.Analizando SQL con Python

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 he implementado un analizador antes, y por lo tanto, me gustaría obtener 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 examinar? Como PLY o Pyparsing.
  • Apuntadores a los artículos, libros o código fuente que me ayudarán se aprecia.

Actualización:

he implementado un simple intérprete de SQL utilizando 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.

+2

¿Por qué imponer limitaciones SQL en los objetos? ¿Qué se gana? ¿Qué pasa con OQL? http://en.wikipedia.org/wiki/Object_Query_Language –

+7

Se debe obtener: una interfaz de consulta que puede usar una gran cantidad de herramientas de informes. Planeo implementar un controlador ODBC en el cliente. Para que los usuarios comerciales puedan usar Crystal Reports, Excel, etc., para obtener datos del almacén de datos. OQL, aunque probablemente sea un buen lenguaje de consulta (nunca lo he usado), no es tan extenso como SQL. – codeape

+1

+1 ambos: uno de los mayores problemas con las bases de datos OO es exactamente la falta de motores de informes :( – van

Respuesta

33

He examinado este tema de forma bastante exhaustiva. 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ándar de sql son 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 gadfly (una base de datos python sql), pero lo evité ya que usaban su propia herramienta de análisis.

Para mi caso, solo necesitaba una cláusula where. Intenté booleneo (un analizador de expresiones booleanas) escrito con pyparsing pero terminé usando pyparsing 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 muy fácilmente para que no sea exactamente igual que sql (la mayoría de la sintaxis no será necesaria). 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 simple integración con python (con fácil devolución de llamada y manejo de errores) hará que la experiencia sea sencilla.

+1

Gracias por compartir sus experiencias. Pruebas iniciales y muy limitadas de python-sqlparse, parece que podría ser capaz de usarlo. Trataré de trabajar con el valor devuelto de la función '' parse'' en python-sqlparse. Pero voy a analizar el pyparsing en en cualquier caso. – codeape

+1

Pyparsing es una buena herramienta para esto, con muchos ejemplos de análisis de sql. –

+2

Este póster en la wiki de pyparsing (http://pyparsing.wikispaces.com/message/view/home/14105203) acaba de informar que se completó un analizador SQL SELECT - quizás podría contactarlo para obtener ayuda, sugerencias o incluso el código. – PaulMcG

9

This reddit post sugiere Python-sqlparse como una implementación existente, entre otros dos enlaces.

+0

Gracias por la sugerencia. Python-sqlparse parece interesante, lo probaré. – codeape

1

Por supuesto, puede ser la mejor manera de aprovechar python-sqlparse on Google Code

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

2

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

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

estoy usando para analizar a cabo consultas de nombres de columna para utilizar en 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']