Sqlalchemy删除子查询

Loo*_*Per 44 python sqlalchemy

我试图使用筛选查询删除一些子行而没有结果:

sl = DBSession.query(Puesto.id).filter(Puesto.locales_id == id).subquery()
DBSession.query(Servicio).filter(Servicio.puestos_id.in_(sl)).delete()
Run Code Online (Sandbox Code Playgroud)

我收到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.
Run Code Online (Sandbox Code Playgroud)

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

任何的想法?

问候

wbe*_*rry 75

查看发生异常的来源后,我建议尝试这样做:

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

有关这意味着什么,请参阅delete方法文档.传递fetch参数将基本上运行查询两次,一次作为选择,一次作为删除.

如果不需要运行两个查询,请synchronize_session=False改为传递,然后session.expire_all()在删除后立即调用,以避免MetaData存储中出现不一致的状态.

  • 由于删除使用带有子查询的“in_”,因此“MetaData”需要“select”查询来决定哪些内存中对象过期。通过此选项将授予其执行此操作的权限。无条件地这样做可能会导致在某些情况下表现不佳。 (3认同)
  • 这个文档还说如果我们立即提交,我们不需要使用autocommit = False调用session.expire_all(). (3认同)
  • @Shafiul你确定吗?我的理解是,如果此删除发生在“提交之后”,而不是“之前”,则不需要调用“expire_all”。如果您在同一数据库事务中执行此删除操作之前执行了其他操作,则会话中的对象可能不再在表中具有任何对应行! (2认同)