2013-09-02 18 views
5

Ho un database SQL che devo conservare le liste di pitone in. Attualmente mi converto la lista in una stringa e poi inserirlo nel database (utilizzando sqlite3) cioèelenchi Memorizzazione Python in 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,)) 

Sembra strano convertire prima la mia lista in una stringa, c'è un modo migliore per farlo?

+0

2 modi. 1. Normalizza le tabelle, è necessario impostare una nuova tabella per il valore di lista. quindi ottieni qualcosa come "TABLE list (id)" e "TABLE list_values ​​(list_id, value)". 2. Puoi serializzare la lista. Ex. Json, XML e così via (non è una buona pratica in SQL). – user1759572

+0

puoi memorizzare i tuoi elenchi come BLOB: http://stackoverflow.com/questions/537077/python-sqlite3-how-to-convert-a-list-to-a-blob-cell – alecxe

risposta

5

Sostituisci il tuo tavolo (key, listdata) con (key, index, listitem). La chiave univoca per la tabella diventa (key, index) anziché solo key e si desidera garantire come condizione di coerenza che l'insieme di indici nella tabella per ogni chiave specificata sia contiguo a partire da 0.

È possibile o meno non è nemmeno necessario distinguere tra una chiave la cui lista è vuota e una chiave che non esiste affatto. Un modo è quello di avere due tabelle (una delle liste e uno dei loro elementi), in modo che una lista vuota ma esistente sia naturalmente rappresentata come una riga nella tabella degli elenchi senza righe corrispondenti nella tabella degli elementi. Un altro modo è solo per fudge e dire che una riga con index=null implica che l'elenco per quella chiave è vuoto.

Si noti che ciò è utile se (e probabilmente solo se) si desidera agire sugli elementi dell'elenco utilizzando SQL (ad esempio, scrivere una query per estrarre l'ultimo elemento di ogni elenco nella tabella). Se non hai bisogno di farlo, allora non è completamente irragionevole trattare i tuoi elenchi come dati opachi nel DB. Stai solo perdendo la capacità del DB di "comprenderlo".

La domanda rimanente è quindi il modo migliore per serializzare/deserializzare l'elenco. str/eval fa il lavoro, ma è un po 'preoccupante. Potresti considerare json.dumps/json.loads, che per un elenco di numeri interi è lo stesso formato di stringa ma con più restrizioni di sicurezza nel parser. Oppure potresti usare una rappresentazione binaria più compatta se lo spazio è un problema.

+1

Una cosa da considerare è che l'OP potrebbe non * avere * realmente bisogno di memorizzare un elenco indicizzato nel DB per cominciare e che i dati potrebbero funzionare concettualmente come un set che può essere ordinato in un secondo momento, ed è possibile utilizzare una relazione 1: N più semplice. Cioè potrebbe essere il caso che l'OP menzioni elenchi principalmente perché sono la raccolta "predefinita" in Python, non perché ha bisogno di tutti i loro comportamenti. – millimoose

+1

@millimoose: buon punto. Se tutto ciò che è veramente necessario è una mappatura 1: N non ordinata (come un Python 'set'), la colonna' index' non è necessaria, anche se ovviamente la colonna 'chiave' deve essere resa non univoca. –

+0

Grazie Steve, questo è proprio quello di cui avevo bisogno. La mia lista Python è una lista 2D con righe indicizzate per data, quindi la userò come valore 'index' nella tabella SQL e memorizzerò il resto della riga corrispondente come dati opachi in' listitem'. – rwolst

0

2 modi.

  1. Normalizza tabelle, è necessario impostare una nuova tabella per il valore di elenco. quindi ottieni qualcosa come "TABLE list (id)" e "TABLE list_values ​​(list_id, value)".

  2. È possibile serializzare l'elenco e inserire una colonna. Ex. Json, XML e così via (non è una buona pratica in SQL).