2011-10-25 76 views
25

我想删除使用过滤查询一些子行无果:SQLAlchemy中删除子查询

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

我得到InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter.的错误。

完整堆栈跟踪:

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. 

我无法找到问题的所在......

任何想法?

问候

回答

53

源寻找您的异常发生后,我建议尝试这样的:

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

对于这意味着什么见documentation of the delete method。通过fetch参数将基本上运行查询两次,一次作为选择,一次作为删除。

如果运行两个查询不希望,通过synchronize_session=False代替,然后调用session.expire_all()后立即MetaData商店内删除对avoid having inconsistent state

+0

第一种方法的伟大工程。为什么现在使用synchronize_session ='evaluate'? – LooPer

+1

因为删除在子查询中使用了“in_”,所以'MetaData'需要一个'select'查询来决定哪个内存对象到期。通过这个选项允许它做到这一点。无条件执行此操作可能会在某些情况下导致性能不佳。 – wberry

+2

这个文档还说如果我们立即提交,我们不需要调用session.expire_all(),autocommit = False。 – giga