У меня есть следующая модель (сильно упрощенная):
class Shipment(Base):
id = Column(Integer, primary_key=True)
account_id = Column(Integer, ForeignKey("accounts.id"))
items = relationship("ShipmentItem")
class ShipmentItem(Base):
id = Column(Integer(), primary_key=True)
shipment_id = Column(Integer, ForeignKey("shipments.id"))
sku = Column(String)
shipment = relationship(Shipment, uselist=False)
product = relationship(
"Product",
primaryjoin="and_(Shipment.id == foreign(ShipmentItem.shipment_id),"
"foreign(ShipmentItem.sku) == Product.sku,"
"foreign(Shipment.account_id) == Product.account_id)",
uselist=False,
)
class Product(Base):
account_id = Column(Integer, ForeignKey("accounts.id"), primary_key=True)
sku = Column(String, primary_key=True)
Обратите внимание, что отношение ShipmentItem.product
не имеет прямой ссылки на Shipment
. Несмотря на это, выполнение shipment_item.product
отлично работает, когда у меня уже есть экземпляр под рукой, но при попытке запросить Shipment.query().filter(Shipment.id == 1).options(defaultload(Shipment.shipment_items).joinedload(ShipmentItem.product))
он не жалуется, что не знает столбец shipments.account_id
.
У меня пытался адаптировать эти документы: https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#composite -secondary-joins к моему случаю, но безрезультатно. Jonedload SQL, который я хотел бы видеть, выглядит примерно так:
SELECT *
FROM shipment_items
JOIN shipments ON shipments.id = shipment_items.shipment_id
JOIN products
ON products.account_id = shipments.account_id
AND shipment_items.sku = products.sku
WHERE shipment_items.shipment_id = 1