【发布时间】:2017-11-13 06:33:11
【问题描述】:
考虑以下使用联合继承的 SQLAlchemy 映射:
from sqlalchemy import sa
class Location(Base):
id = Column(Integer, primary_key=True)
name = sa.Column(sa.String)
type_ = sa.column(sa.String)
__tablename__ = 'location'
__mapper_args__ = {
'polymorphic_identity': 'location',
'polymorphic_on': type_,
}
class Field(Location):
id = Column(Integer, primary_key=True)
size = sa.Column(sa.Float)
__tablename__ = 'field'
__mapper_args__ = {
'polymorphic_identity': 'field',
}
__table_args__ = (
sa.ForeignKeyConstraint(['id'], ['location.id']),
)
session.query(Field).filter(Field.size < 5).delete()
其中 base 是一个适当的声明基础, session 是一个适当的会话对象。上面的实现将导致 Field 对象被删除而不删除父 Location 对象(正如文档清楚地解释,query.delete() 不支持继承)。我可以通过 session.delete(obj) 来解决这个问题,它使用 ORM 删除链上的对象。但是,这会导致在数据库上执行 n 个 SQL 删除语句(其中 n 是要删除的对象数)。我有一个案例,我可能一次删除大约 100,000 个子对象,所以这个操作非常慢(假设现在我不可能不使用 ORM 和加入继承 - 我太深了,无法更改)。
SQLAlchemy 中是否有任何构造或合理的替代方法,可以让我传递一个查询对象,该查询对象查询 Field 类型的对象并适当地删除 Location 表中的项目,而无需制作 n SQL 删除语句?
注意,我目前使用的是 PostgreSQL,但想保留解决方案 db-agnostic。
编辑:根据请求添加了表元数据和有关环境的更多信息。
【问题讨论】:
-
请包括您使用的数据库以及主键和外键定义。您可以为此使用 Core。
标签: python inheritance sqlalchemy