У меня есть следующие самоссылочные отношения (Подсеть -> Подсеть), а также связь с таблицей сопоставления (SecurityZoneSubnetMap -> Подсеть):
class Subnet(Base):
...
paired_subnet_id = Column(BigInteger, ForeignKey("Subnet.subnet_id", ondelete="SET NULL"), nullable=True)
subnet_zone = relationship("SecurityZoneSubnetMap", cascade="all, delete-orphan", uselist=False)
...
paired_subnet = relationship("Subnet", primaryjoin="Subnet.paired_subnet_id==Subnet.subnet_id", uselist=False)
class SecurityZoneSubnetMap(Base):
"""SecurityZone to Subnet 1-to-many mapping."""
__tablename__ = "SecurityZoneSubnetMap"
zone_id = Column(BigInteger, ForeignKey("SecurityZone.zone_id", ondelete="CASCADE"), primary_key=True, nullable=False)
subnet_id = Column(BigInteger, ForeignKey("Subnet.subnet_id", ondelete="CASCADE"), primary_key=True, nullable=False)
zone = relationship("SecurityZone", uselist=False)
subnet = relationship("Subnet", uselist=False)
Что я хотел бы сделать, этонаписать запрос, который активно загружает «subnet_zone» как для подсети, так и для сопряженной подсети. Так что я могу получить доступ ко всем следующим без дополнительных запросов O + 1:
subnet.subnet_zone
subnet.paired_subnet
subnet.paired_subnet.subnet_zone
Я хотел бы сделать это без изменения схем, если это возможно.
Я ужепопробовал что-то вроде следующего:
paired_subnet = aliased(inv.Subnet)
paired_security_zone_subnet_map = aliased(inv.SecurityZoneSubnetMap)
subnets = self._session.query(inv.Subnet)
.join(paired_subnet, inv.Subnet.subnet_id == paired_subnet.paired_subnet_id)
.outerjoin(paired_security_zone_subnet_map, paired_subnet.subnet_id == paired_security_zone_subnet_map.subnet_id)
.options(contains_eager(inv.Subnet.paired_subnet, alias=paired_subnet).contains_eager(paired_subnet.subnet_zone, alias=paired_security_zone_subnet_map))
.all()
)