2013-10-02 17 views
10

Bene, ho a che fare con un dubbio su sqlalchemy e sugli oggetti che si aggiornano!Informazioni sull'aggiornamento di oggetti nella sessione sqlalchemy

Sono nella situazione in quello che ho 2 sessioni, e lo stesso oggetto è stato interrogato in entrambe le sessioni! ... Per alcune cose particolari non riesco a chiudere una delle sessioni. Ho modificato l'oggetto e ho eseguito i cambiamenti nella sessione A, ma nella sessione B, gli attributi sono quelli iniziali! senza modifiche! ..

Quindi ... devo implementare un qualche tipo di sistema di notifica per comunicare le modifiche o esiste un modo integrato per farlo in sqlalchemy ??

+1

http://stackoverflow.com/a/18684124/1309352 –

+0

Questo può aiutare pure : http://stackoverflow.com/a/25694346/134904 – kolypto

risposta

17

Sessions are designed to work like this. Gli attributi dell'oggetto nella Sessione B manterranno ciò che aveva quando interrogato per la prima volta nella Sessione B. Inoltre, SQLAlchemy non tenterà di aggiornare automaticamente gli oggetti in altre sessioni quando cambiano, né penso che sarebbe saggio provare a creare qualcosa come questo.

Si dovrebbe pensare attivamente alla durata di ogni sessione come una singola transazione nel database. Come e quando le sessioni devono affrontare il fatto che i loro oggetti potrebbero essere stantii non è un problema tecnico che può essere risolto da un algoritmo incorporato in SQLAlchemy (o qualsiasi estensione per SQLAlchemy): si tratta di un problema di "business" la cui soluzione è necessario determinare e codice te stesso. La risposta "corretta" potrebbe essere quella di dire che questo non è un problema: la logica che si verifica con la Sessione B potrebbe essere valida se ha usato i dati nel momento in cui la Sessione B è iniziata. Il tuo "problema" potrebbe non essere effettivamente un problema. La documentazione in realtà hanno un entire section on when to use sessions, ma dà una risposta piuttosto triste se si spera per un one-size-fits-all soluzione ...

Una Sessione è tipicamente costruito all'inizio di un'operazione logica dove l'accesso al database è potenzialmente anticipato.

La Sessione, ogni volta che viene utilizzata per comunicare con il database, avvia una transazione di database non appena inizia la comunicazione. Supponendo che il contrassegno autocommit sia lasciato al valore predefinito consigliato di False, questa transazione rimane in corso fino a quando la sessione non viene ripristinata, confermata o chiusa. La Session inizierà una nuova transazione se viene utilizzato nuovamente , successivamente alla conclusione della transazione precedente; da questo segue che la Sessione è in grado di avere una durata di vita attraverso molte transazioni, anche se solo una alla volta. Ci riferiamo a questi due concetti come ambito della transazione e ambito della sessione.

L'implicazione è che la SQLAlchemy ORM sta incoraggiando lo sviluppatore per stabilire questi due ambiti nella sua applicazione, tra cui non solo quando gli scopi inizio e la fine, ma anche la distesa di tali ambiti, ad esempio una singola istanza di sessione deve essere locale per il flusso di esecuzione all'interno di una funzione o metodo, dovrebbe essere un oggetto globale utilizzato dall'intera applicazione o da qualche parte tra questi due.

L'onere assegnato allo sviluppatore per determinare questo ambito è un'area in cui l'ORM SQLAlchemy ha necessariamente una forte opinione su come utilizzare il database . L'unità di modello di lavoro è specificatamente uno dei cambiamenti accumulatori nel tempo e il loro svuotamento periodico, mantenendo lo stato in memoria in sincronia con ciò che è noto essere presente in una transazione locale .Questo modello è efficace solo quando sono presenti significativi ambiti di transazione .

Detto questo, ci sono alcune cose che puoi fare per cambiare come funziona la situazione:

In primo luogo, è possibile ridurre per quanto tempo la sessione rimane aperta. La sessione B sta interrogando l'oggetto, quindi in seguito si sta facendo qualcosa con quell'oggetto (nella stessa sessione) in cui si desidera che gli attributi siano aggiornati. Una soluzione consiste nel fare questa seconda operazione in una sessione separata.

altro è quello di utilizzare i metodi di aggiornamento scadere /, come il docs show ...

# immediately re-load attributes on obj1, obj2 
session.refresh(obj1) 
session.refresh(obj2) 

# expire objects obj1, obj2, attributes will be reloaded 
# on the next access: 
session.expire(obj1) 
session.expire(obj2) 

È possibile utilizzare session.refresh() ottenere immediatamente una versione up-to-data dell'oggetto, anche se la sessione già ha interrogato l'oggetto in precedenza.

+0

Thx! Voglio dire di aver letto la documentazione completa delle sessioni. Ma, anche dopo averlo fatto, ho qualche problema nel definire dove iniziare la sessione e dove terminarlo nel mio codice applicativo, e che non è nella documentazione haha. –

+0

Quando e come utilizzare le sessioni sarà diverso da un'applicazione all'altra. Non esiste una soluzione adatta a tutte le soluzioni e descrive come si procederebbe nel processo di determinazione che potrebbe essere un intero libro stesso. Quindi, non stare male che non sei sicuro di come farlo, dal momento che non è un problema semplice. –

+0

beh, dicendo questo, mi sento più libero di creare un flusso di lavoro che soddisfi i miei bisogni, e non cerco di trovare un modello dove non può esistere! –

Problemi correlati