2011-10-25 14 views
25

sto cercando di eliminare alcune righe figlio utilizzando una query filtrata senza risultato:SQLAlchemy cancellare subquery

sl = DBSession.query(Puesto.id).filter(Puesto.locales_id == id).subquery() 
DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)).delete() 

sto ottenendo InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter. come errore.

completa analisi dello stack:

Traceback (most recent call last): 
    File "/usr/src/tg2env/ceaf/ceaf/controllers/root.py", line 1673, in delete_local 
    DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)).delete() 
    File "/usr/src/tg2env/lib/python2.4/site-packages/SQLAlchemy-0.6.6-py2.4.egg/sqlalchemy/orm/query.py", line 2126, in delete 
    raise sa_exc.InvalidRequestError(
InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter. 

io non sono in grado di trovare dove il problema è ...

Qualche idea?

saluti

risposta

53

Dopo aver guardato nella sorgente in cui si verifica il tuo eccezione vi suggerisco di provare questo:

sl = DBSession.query(Puesto.id).filter(Puesto.locales_id == id).subquery() 
DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)) \ 
.delete(synchronize_session='fetch') 

Vedere la documentation of the delete method per ciò che questo significa. Passando l'argomento fetch verrà eseguita la query due volte, una volta come selezione e una volta come eliminazione.

Se l'esecuzione due query non è desiderato, passare synchronize_session=False invece e quindi chiamare session.expire_all() subito dopo l'eliminazione al avoid having inconsistent state all'interno del negozio MetaData.

+0

Il primo approccio funziona alla grande. Perché ora lavorare con synchronize_session = 'valutare'? – LooPer

+1

Poiché l'eliminazione utilizza 'in_' con una sottoquery, è necessaria una query' select' per 'MetaData' per decidere quale dei suoi oggetti in memoria scade. Passare questa opzione dà il permesso di farlo. Farlo incondizionatamente rischierebbe di ottenere prestazioni scadenti in determinate situazioni. – wberry

+2

Questo documento dice anche che se commettiamo immediatamente, non è necessario chiamare session.expire_all(), con autocommit = False. – giga