如何使用不带ORM的SQLAlchemy查询从表中删除行?

2024-05-23 18:06:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个快速而脏的维护脚本来删除一些行,并且希望避免将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时,我很环保,我应该怎么做呢?


Tags: 项目脚本内容addresssessionaddressesormtable
2条回答

当从查询对象调用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)

通过一些代码,我做了类似的事情,我相信这将做你想要的。

d = addresses_table.delete().where(addresses_table.c.retired == 1)
d.execute()

在表对象上调用delete()会给您一个sql.expression(如果内存可用),然后您可以执行它。我在上面假设表绑定到一个连接,这意味着您可以对它调用execute()。如果不是,则可以在连接上将d传递给execute(d)

参见文档here

相关问题 更多 >