我有两个班级:
一个交易有多个 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
但是当我得到贸易对象时,它拥有所有贸易项目并且完全忽略过滤条件。
答案 0 :(得分:0)
您可以使用 contains_eager 选项仅加载过滤器选择的子行。
请注意,要创建 WHERE ... AND ...
过滤器,您可以使用 sqlalchemy.and_,或链接 filter
或 filter_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