2012-08-04 17 views
10

Wyobraź sobie, że masz słownik Pythona o wartości klucz-wartość (lub listę) z większą ilością elementów. Powiedzmy, że czytasz większy plik JSON i chcesz zapisać jego zawartość w tabeli MySQL z kluczami jako nazwami kolumn i wartości jako wartościami.Jaki jest najskuteczniejszy sposób wstawiania słowników/list w języku Python do bazy danych SQL?

JSON Przykład:

"display_location": { 
    "city":"Bratislava", 
    "state_name":"Slovakia", 
    "country_iso3166":"SK", 
    "latitude":"48.20000076", 
    "longitude":"17.20000076", 
} 

Wtedy jest zupełnie nieefektywne napisać wkładkę SQL jak to ręcznie:

INSERT INTO TABLE (city, state_name, country_iso3166, latitude, longitude) VALUES('%s','%s','%s','%s','%s') 
% (Bratislava, Slovakia, SK, 48.20000076, 17.20000076); 

(Cóż, to ok z pięciu wartości, ale wyobraź sobie, są na przykład pięć setki z nich.)

Czy istnieje klasa/metoda Pythona do efektywnego wstawiania kodu SQL w krótkich strojach? Napisałem ten kawałek kodu:

for key,value in list.iteritems(): 
    value_type = type(value) 
    if value_type is unicode: 
     vars_to_sql.append(value.encode('ascii', 'ignore')) 
     keys_to_sql.append(key.encode('ascii', 'ignore')) 
    else: 
     vars_to_sql.append(value) 
     keys_to_sql.append(key) 

keys_to_sql = ', '.join(keys_to_sql) 

Po że wkładka wygląda o wiele bardziej prosta:

INSERT INTO conditions_bratislava(%s) VALUES %r" % (keys_to_sql, tuple(vars_to_sql),) 

Nie może być tysiące wartości i nadal będzie w porządku z tym stwierdzeniem jeden wkładki.

Należy zauważyć, że warunek, który będzie dekodować ciągi Unicode, więc nie będziesz miał liter "u" przed każdą wartością.

Czy istnieje jakaś bardziej efektywna i przygotowana klasa lub metoda jak wstawiać wiele wartości w tym samym prostym podejściu z krótkim ciągiem INSERT?

+1

Jeśli chcesz użyć relacyjnej bazy danych, może użyć nadchodzącego PostgreSQL 9.2, który ma natywny typ danych JSON. –

Odpowiedz

6

Jeśli dane jest skonstruowany tak, że to nadaje się bardziej zorientowane w kierunku dokumentu bazy danych (Mongo/Couch etc ...)

Można uciec z czymś takim ... Myślę, używając repr jest zbyt mądry ...

insert_sql = 'INSERT INTO conditions_bratislava(%s) values(%s)' 
cols = ', '.join(somedict) 
vals = ', '.join('?' * len(somedict)) # or whatever qparam is required 
to_execute = insert_sql % (cols, vals) 
some_cursor.execute(to_execute, somedict.values()) 

na marginesie:

value_type = type(value) 
if value_type is unicode: 

powinien być zapisany jako:

if isinstance(value, unicode): 
+0

+1 na 'isinstance' –

+0

Jeśli dyktaturę zmodyfikowano w drugim wątku, może to spowodować niepoprawną kolejność wartości lub zbyt wiele wartości. Zamiast tego użyłbym nazwanych parametrów i przekazał cały słownik do kursora.execute. – XORcist

+0

@ möter Oferowałem "bardziej poprawną" wersję tego, co robił OP. Zgadzam się, że używanie nazwanych parametrów jest ogólnie nieco lepsze. Mam również nadzieję, że każdy, kto używa wątków, będzie na tyle ostrożny, by używać blokady. –

Powiązane problemy