Consider the following SQLAlchemy mappings using joined inheritance:
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()
Where base is an appropriate declarative base and session is an appropriate session object. The implementation of the above will cause the Field objects to be deleted without the parent Location objects from being deleted (as the docs explain clearly, query.delete() does not support inheritance). I can get around this by doing session.delete(obj) which uses the ORM to delete objects up the chain. However, this causes n SQL delete statements to be executed on the database (where n is the number of objects to delete). I have a case where I may be deleting in the order of 100,000 child objects at a time, so this operation is horribly slow (assume for now that it is impossible for me to not use the ORM with joined inheritance - I am too deep to change this).
Is there any construct within SQLAlchemy or a reasonable alternative which would allow me to pass a query object that queries objects of type Field and appropriately deletes the items in the Location table as well without making n SQL delete statements?
Note, I am currently using PostgreSQL, but would like to keep the solution db-agnostic.
Edit: Added table metadata and more information regarding environment as per request.