2011-11-24 15 views
34

Per varie ragioni, sto cercando di ottenere un insieme di oggetti da un database e di passarlo a un altro processo che non è connesso al database. Il mio codice è come quella qui sotto, ma continuo a ricevereSQLAlchemy, ottenere oggetto non associato a una sessione

sqlalchemy.exc.UnboundExecutionError: Instance <MyClass at 0x8db7fec> is not bound to a Session; attribute refresh operation cannot proceed 

Quando cerco di guardare gli elementi della mia lista al di fuori del metodo get_list().

def get_list (obj): 
    sesson = Session() 
    lst = session.query(MyClass).all() 
    session.close() 
    return lst 

Tuttavia, se uso questo

def get_list_bis (obj) 
    session = Session() 
    return session.query(MyClass).all() 

sono in grado di utilizzare gli elementi, ma preoccuparsi per lo stato della sessione in quanto non è stato chiuso.

Cosa mi manca qui?

risposta

39

Se si desidera che un gruppo di oggetti prodotti mediante l'interrogazione di una sessione sia utilizzabile al di fuori dell'ambito della sessione, è necessario effettuare il expunge per la sessione.

Nel tuo primo esempio funzione, è necessario aggiungere una riga:

session.expunge_all() 

prima

session.close() 

Più in generale, diciamo che la sessione non è chiusa subito, come nel primo esempio. Forse questa è una sessione che viene mantenuta attiva durante l'intera durata di una richiesta web o qualcosa del genere. In questi casi, non si desidera eseguire expunge_all. Si vuole essere più chirurgica:

for item in lst: 
    session.expunge(item) 
+17

Ma ... ma ... "Il metodo close() emette un expunge_all() e rilascia qualsiasi risorsa di transazione/connessione." Questa affermazione è nella pagina a cui si fa riferimento, almeno per quanto riguarda la versione 0.6. – Oddthinking

1

Nel mio caso, mi è stato il salvataggio di un ente collegato come bene, e questa ricetta mi ha aiutato a refresh tutte le istanze all'interno di una sessione, sfruttando il fatto che la sessione è iterabile:

map(session.refresh, iter(session)) # call refresh() on every instance 

Ciò è estremamente inefficace, ma funziona. Dovrebbe andare bene per i test unitari.

Nota finale: in Python3 map() è un generatore e non farà nulla. Utilizzare i loop reali di list comprehensions

+4

In ogni caso, non dovresti usare 'map' se non ti interessa il risultato. – ThiefMaster

Problemi correlati