2009-09-08 16 views
38

Chcę utworzyć interfejs SQL na szczycie nierelacyjnej składnicy danych. Nie-relacyjny magazyn danych, ale ma sens dostęp do danych w sposób relacyjny.Parsowanie SQL za pomocą Pythona

Szukam przy użyciu ANTLR do tworzenia AST, który reprezentuje SQL jako relacyjne wyrażenie algebry. Następnie zwróć dane, oceniając/chodząc po drzewie.

Nigdy wcześniej nie zaimplementowałem analizatora składni, dlatego chciałbym poradzić się, jak najlepiej zaimplementować parser SQL i ewaluator.

  • Czy opisane powyżej podejście brzmi poprawnie?
  • Czy są inne narzędzia/biblioteki, które powinienem zaglądać? Podobnie jak PLY lub Pyparsing.
  • Wskazywanie na artykuły, książki lub kod źródłowy, które mi pomogą, jest doceniane.

Aktualizacja:

I wdrożone prosty parser SQL przy użyciu pyparsing. W połączeniu z kodem Pythona, który implementuje relacyjne operacje na moim magazynie danych, było to dość proste.

Jak już powiedziałem w jednym z komentarzy, celem ćwiczenia było udostępnienie danych silnikom raportującym. Aby to zrobić, prawdopodobnie będę musiał zaimplementować sterownik ODBC. To prawdopodobnie dużo pracy.

+2

Po co nakładać ograniczenia SQL na obiekty? Co można zyskać? Co jest nie tak z OQL? http://en.wikipedia.org/wiki/Object_Query_Language –

+7

Do zdobycia: Interfejs zapytań, z którego może korzystać ogromna liczba narzędzi do raportowania. Planuję wdrożyć sterownik ODBC na kliencie. Aby użytkownicy biznesowi mogli używać Crystal Reports, Excel itp. Do pobierania danych ze składnicy danych. OQL, chociaż prawdopodobnie ładny język zapytań (nigdy go nie używałem), nie jest tak szeroko rozpowszechniony jak SQL. – codeape

+1

+1 oba: jednym z największych problemów z bazami OO jest właśnie brak silników raportujących :( – van

Odpowiedz

33

Zajrzałem do tej kwestii dość szeroko. Python-sqlparse to niepatalizujący analizator składni, który w rzeczywistości nie jest tym, czego potrzebujesz. Przykłady w antlr wymagają dużo pracy, aby przekonwertować do nice ast w python. Standardowe gramatyki sql to here, ale byłoby to pełnoetatowe zlecenie, aby samemu je przekonwertować i prawdopodobnie będzie potrzebny tylko ich podzbiór, tj. Brak złączeń. Możesz spróbować spojrzeć na gadfly (bazy danych sql Pythona), ale uniknąłem go, ponieważ użyli własnego narzędzia parsowania.

W moim przypadku, zasadniczo potrzebowałem tylko klauzuli where. Próbowałem booleneo (boolean wyrażeń parser) napisane z pyparsing, ale zakończył się przy użyciu pyparsing od zera. Pierwszy odnośnik w postu reddita Marka Rushakoffa daje przykład sql z jego użyciem. Whoosh wykorzystuje ją również wyszukiwarka pełnotekstowa, ale nie przyjrzałem się źródłu, aby zobaczyć, jak to zrobić.

Pyparsing jest bardzo łatwy w użyciu i można go bardzo łatwo dostosować, aby nie był dokładnie taki sam jak sql (większość składni nie będzie potrzebna). Nie podobało mi się używanie warstwy, ponieważ używa jakiejś magii używając konwencji nazewnictwa.

Podsumowując, można wypróbować, najprawdopodobniej będzie wystarczająco potężny, aby zrobić to, czego potrzebujesz, a prosta integracja z pythonem (z łatwym wywoływaniem zwrotnym i obsługą błędów) sprawi, że twoje doświadczenie będzie dość bezbolesne.

+1

Dzięki za podzielenie się swoimi doświadczeniami. początkowe, bardzo ograniczone testy Pythona-sqlparse, wydaje mi się, że mogę go użyć.Spróbuję pracować z zwróconą wartością z funkcji '' parsuj'' w python-sqlparse, ale zajrzę do pyparsingu w każdym przypadku: – codeape

+1

Pyparsing jest dobrym narzędziem do tego, z mnóstwem przykładów parsowania sql wokół. –

+2

Ten plakat na wiki pyparsing (http://pyparsing.wikispaces.com/message/view/home/14105203) właśnie zgłosił zakończenie parser SQL SELECT - być może mógłbyś skontaktować się z nim w sprawie pomocy, sugestii, a nawet kodu – PaulMcG

2

TwoLaid za Python SQL Parser działa bardzo dobrze dla moich celów . Jest napisany w C i wymaga kompilacji. Jest solidny.Analizuje poszczególne elementy każdej klauzuli.

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

Używam go do analizowania z zapytań nazw kolumn do wykorzystania w nagłówkach raportów. Oto przykład.

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'] 
Powiązane problemy