SQLAlchemy中的通用查询

时间:2013-09-09 11:27:49

标签: python sqlalchemy querying

我有以下代码:

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'))

目前我有一个条目(作者或Horizo​​nt或任何其他与arch.record相关的条目)。我想确保没有任何一条记录引用此字段。但我讨厌为每个案例编写很多代码,并希望以最常见的方式进行。

所以,实际上我有:

  • ArchaeologicalRecord的实例
  • 子实体的实例,例如,Horizo​​nt
  • (来自之前)它的类定义。

如何在不编写大量复制粘贴代码的情况下检查ArchaeologicalRecord是否包含(或不)引用Horizont(或任何其他子实体)?

1 个答案:

答案 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_属性应该以通用的方式为您提供所需的所有信息。