SQLAlchemy 关系过滤器不起作用

时间:2021-01-19 16:05:32

标签: python sqlalchemy orm

我有两个班级:

  • 贸易
  • 贸易项目

一个交易有多个 TradeItem。这是一个简单的一对多关系。

贸易

class Trade(Base):
    __tablename__ = 'trade'
    id = Column(Integer, primary_key=True)
    name= Column(String)

    trade_items = relationship('TradeItem',
                            back_populates='trade')

贸易项目


class TradeItem(Base):
    __tablename__ = 'trade_item'
    id = Column(Integer, primary_key=True)
    location = Column(String)
    trade_id = Column(Integer, ForeignKey('trade.id'))

    trade = relationship('Trade',
                            back_populates='trade_items')

过滤

session.query(Trade).filter(Trade.name == trade_name and TradeItem.location == location)

我想按名称获取贸易对象,并且仅获取位置与给定位置名称匹配的那些贸易项目。

所以如果有一个交易对象:Trade(name='Trade1') 并且它有 3 个项目: TradeItem(location='loc1'),TradeItem(location='loc2'),TradeItem(location='loc2')

然后查询应该只返回我的交易目标交易项目:

session.query(Trade).filter(Trade.name == 'Trade1' and TradeItem.location == 'loc1').first()

然后我希望查询返回名为 Trade1 的 Trade,但只有一个 Trade 项目填充了 location 为 loc1

但是当我得到贸易对象时,它拥有所有贸易项目并且完全忽略过滤条件。

1 个答案:

答案 0 :(得分:0)

您可以使用 contains_eager 选项仅加载过滤器选择的子行。

请注意,要创建 WHERE ... AND ... 过滤器,您可以使用 sqlalchemy.and_,或链接 filterfilter_by 方法,但使用 Python 的逻辑 and 将无法按预期工作.

from sqlalchemy import orm, and_

trade = (session.query(Trade)
         .filter(and_(Trade.name == 'Trade1', TradeItem.location == 'loc1'))
         .options(orm.contains_eager(Trade.trade_items))
         .first())

查询生成此 SQL :

SELECT trade_item.id AS trade_item_id, trade_item.location AS trade_item_location, trade_item.trade_id AS trade_item_trade_id, trade.id AS trade_id, trade.name AS trade_name 
FROM trade 
JOIN trade_item ON trade.id = trade_item.trade_id 
WHERE trade.name = 'trade1' AND trade_item.location = 'loc1'
 LIMIT 1 OFFSET 0