2013-09-02 20 views
5

Mam bazę danych SQL, że przechowywanie list Python w. Obecnie przekonwertować listę do łańcucha, a następnie włóż ją do bazy danych (przy użyciu sqlite3) tjListy Przechowywanie Python w SQL Database

foo = [1,2,3] 
foo = str(foo) 

#Establish connection with database code here and get cursor 'cur' 

cur.execute("INSERT INTO Table VALUES(?, ?)", (uniqueKey, foo,)) 

Wydaje dziwne, aby najpierw przekonwertować moją listę na ciąg, czy jest lepszy sposób na zrobienie tego?

+0

2 sposoby. 1. Normalizuj tabele, aby ustawić nową tabelę dla wartości listy. więc dostajesz coś w rodzaju "TABLE list (id)" i "TABLE list_values ​​(list_id, value)". 2. Możesz serializować listę. Dawny. Json, XML i tak dalej (nie jest to bardzo dobra praktyka w SQL). – user1759572

+0

możesz przechowywać swoje listy jako obiekty blob: http://stackoverflow.com/questions/537077/python-sqlite3-how-to-convert-a-list-to-a-blob-cell – alecxe

Odpowiedz

5

Wymień swoją tabelę (key, listdata) z (key, index, listitem). Klucz unikalny dla tabeli staje się (key, index) zamiast tylko key, a będziesz chciał zapewnić jako warunek zgodności, że zestaw indeksów w tabeli dla dowolnego klucza jest ciągły, zaczynając od 0.

Możesz lub nie możesz nie trzeba również rozróżniać klucza, którego lista jest pusta, i klucza, który w ogóle nie istnieje. Jednym ze sposobów jest posiadanie dwóch tabel (jednej z list i jednego z ich elementów), tak aby pusta, ale istniejąca lista była naturalnie reprezentowana jako wiersz w tabeli list bez odpowiednich wierszy w tabeli elementów. Innym sposobem jest po prostu fałszowanie go i powiedzenie, że wiersz z index=null oznacza, że ​​lista dla tego klucza jest pusta.

Warto zauważyć, że jest to opłacalne, jeśli (i prawdopodobnie tylko jeśli) chcemy działać na elementach listy za pomocą SQL (na przykład pisząc zapytanie, aby wyciągnąć ostatni element z każdej listy w tabeli). Jeśli nie musisz tego robić, to nie jest to nieuzasadnione, aby traktować twoje listy jako nieprzejrzyste dane w bazie danych. Po prostu tracisz zdolność DB do "zrozumienia" tego.

Pozostaje pytanie, jak najlepiej serializować/deserializować listę. str/eval wykonuje zadanie, ale jest trochę niepokojące. Możesz rozważyć: json.dumps/json.loads, która dla listy liczb całkowitych ma taki sam format ciągu znaków, ale z większą ilością ograniczeń bezpieczeństwa w analizatorze składni. Lub możesz użyć bardziej kompaktowej reprezentacji binarnej, jeśli przestrzeń jest problemem.

+1

Jedną z rzeczy do rozważenia jest to, że OP niekoniecznie * potrzebuje * do przechowywania indeksowanej listy w DB, a twoje dane mogą koncepcyjnie działać tak dobrze, jak zestaw, który można później posortować, i możesz użyć prostszej relacji 1: N. To znaczy. może się zdarzyć, że OP wymienia listy głównie dlatego, że są "domyślną" kolekcją w Pythonie, nie dlatego, że potrzebuje wszystkich swoich zachowań. – millimoose

+1

@millimoose: dobry punkt. Jeśli naprawdę potrzebne jest mapowanie nieuporządkowane 1: N (jak "zestaw" Pythona), to kolumna 'index' nie jest potrzebna, chociaż oczywiście kolumna' klucz' musi być unikatowa. –

+0

Dzięki Steve, to jest właśnie to, czego potrzebowałem. Moja lista Pythona jest listą 2D z wierszami indeksowanymi według dat, więc użyję jej jako wartości 'index' w tabeli SQL i zapiszę resztę odpowiedniego wiersza jako nieprzezroczyste dane w' listitem'. – rwolst

0

2 sposoby.

  1. Normalizuj tabele, aby ustawić nową tabelę dla wartości listy. więc dostajesz coś w rodzaju "TABLE list (id)" i "TABLE list_values ​​(list_id, value)".

  2. Możesz serializować listę i umieścić w kolumnie. Dawny. Json, XML i tak dalej (nie jest to bardzo dobra praktyka w SQL).

Powiązane problemy