我正在编写一个快速而脏的维护脚本来删除一些行,并且希望避免从主项目中删除我的ORM类/映射。我的查询类似于:
address_table = Table('address',metadata,autoload=True)
addresses = session.query(addresses_table).filter(addresses_table.c.retired == 1)
根据我读过的所有内容,如果我使用的是ORM(不是'只是'表格)并传递了类似的内容:
addresses = session.query(Addresses).filter(addresses_table.c.retired == 1)
我可以在查询中添加.delete()
,但当我尝试仅使用表格时,我会收到投诉:
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 2146, in delete
target_cls = self._mapper_zero().class_
AttributeError: 'NoneType' object has no attribute 'class_'
这是一个有意义的表,而不是一个类。对于SQLAlchemy来说,我是非常环保的,我该怎么做呢?
答案 0 :(得分:33)
通过一些我做过类似代码的代码,我相信这会做你想要的。
d = addresses_table.delete().where(addresses_table.c.retired == 1)
d.execute()
在表对象上调用delete()
会为您提供sql.expression
(如果内存服务),然后执行。我假设上面的表绑定了一个连接,这意味着你可以在它上面调用execute()
。如果没有,您可以将d
传递给execute(d)
连接。
请参阅文档here。
答案 1 :(得分:25)
当您从查询对象调用delete()
时,SQLAlchemy会执行批量删除。您需要选择策略来从会话中删除匹配的对象。请参阅文档here。
如果您没有选择从会话中删除匹配对象的策略,那么SQLAlchemy将尝试直接在会话中的对象上评估Python中的查询条件。 如果未执行评估标准,则会出现错误。
删除时会发生这种情况。
如果您只想删除记录而不关心删除后会话中的记录,则可以选择忽略会话同步的策略:
address_table = Table('address', metadata, autoload=True)
addresses = session.query(address_table).filter(address_table.c.retired == 1)
addresses.delete(synchronize_session=False)