我有以下映射的类定义
class A(Base):
__tablename__ = "a"
id = sqla.Column(sqla.Integer, primary_key = True)
number_a = sqla.Column(sqla.Integer)
b_collection = relationship('B', backref = backref('a'))
class B(Base):
__tablename__ = "b"
id = sqla.Column(sqla.Integer, primary_key = True)
id_a = sqla.Column(sqla.Integer, sqla.ForeignKey('a.id'))
number_b = sqla.Column(sqla.Integer)
这些对象存储在DB中:
a1 = A(number_a = 1)
a2 = A(number_a = 2)
b1 = B(number_b = 50, a = a2)
b2 = B(number_b = 51, a = a2)
我需要的是通过仅发出一个查询来查询关系,以便仅通过该查询的结果预加载b_collection
:
result = session.query(A).join(B).filter(B.number_b == 51).all()
所以现在我希望result[0].b_collection
尊重过滤表达式,不要包含B
实例with number_b = 50
。所以我的预期输出:
for a in result:
for b in a.b_collection:
print(b.number_b)
将是:
51
然而,迭代a.b_collection
总是发出新查询并将B
个对象加载到b_collection
中,以便结果为
50
51
这是我不想要的。
如何强制原始查询加载所有对象并根据给定的过滤条件填充关系集合?
感谢您的回复。
答案 0 :(得分:2)
使用contains_eager
执行此操作,但请注意您欺骗 SQL Alchemy,因此请勿重复使用此 UnitOfWork 来执行与常规关系相关的任务:
result = (
session.query(A)
.join(B)
.filter(B.number_b == 51)
.options(contains_eager(A.b_collection)) # this is the key
).all()