Вторичное соединение в отношении "один ко многим" в SQLAlchemy - PullRequest
0 голосов
/ 10 июля 2020

У меня есть следующая модель (сильно упрощенная):

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...