我有以下代码:
class ArchaeologicalRecord(Base, ObservableMixin, ConcurrentMixin):
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship('Author', backref=backref('record'))
horizont_id = Column(Integer, ForeignKey('horizonts.id'))
horizont = relationship('Horizont', backref=backref('record'))
.....
somefield_id = Column(Integer, ForeignKey('somefields.id'))
somefield = relationship('SomeModel', backref=backref('record'))
目前我有一个条目(作者或Horizont或任何其他与arch.record相关的条目)。我想确保没有任何一条记录引用此字段。但我讨厌为每个案例编写很多代码,并希望以最常见的方式进行。
所以,实际上我有:
如何在不编写大量复制粘贴代码的情况下检查ArchaeologicalRecord
是否包含(或不)引用Horizont
(或任何其他子实体)?
答案 0 :(得分:1)
你在问如何找到孤儿作者,horzonts,某些领域吗?
假设您的所有关系都是多对一的(ArchaelogicalRecord-to-Author),您可以尝试以下方式:
from sqlalchemy.orm.properties import RelationshipProperty
from sqlalchemy.orm import class_mapper
session = ... # However you setup the session
# ArchaelogicalRecord will have various properties defined,
# some of these are RelationshipProperties, which hold the info you want
for rp in class_mapper(ArchaeologicalRecord).iterate_properties:
if not isinstance(rp, RelationshipProperty):
continue
query = session.query(rp.mapper.class_)\
.filter(~getattr(rp.mapper.class_, rp.backref[0]).any())
orphans = query.all()
if orphans:
# Do something...
print rp.mapper.class_
print orphans
当rp.backref为None(即你已经定义了没有backref的关系的地方)时,这将失败 - 在这种情况下,您可能需要手动构建查询,但是RelationshipProperty,它就是。 mapper和.mapper.class_属性应该以通用的方式为您提供所需的所有信息。