假设我有2个课程:Foo和Bar。假设一个Foo可以有很多Bar(通过foo.Bars)。栏有一个end_date来指示栏何时结束。未结束的条形图默认设置为“9999-12-31”。
我在下面写了两个查询来获取Foo但是使用不同的条形过滤器,这样第一个查询就会给我一些尚未结束的条形图;第二个给了我已经结束的酒吧。
today = date.today().strftime("%Y-%m-%d")
current = session.query(Foo)\
.join(Bar)\
.filter(
and_(
Foo.code=='MY_STRING',
Bar.end_date >= today,
)
)\
.options(contains_eager('Bars'))\
.one()
previous = session.query(Foo)\
.join(Bar)\
.filter(
and_(
Foo.code=='MY_STRING',
Bar.end_date < today,
)
)\
.options(contains_eager('Bars'))\
.one()
由于某种原因,previous.Bars与current.Bars相同,即使我们已经过滤了不同的栏(至少这是我的尝试)。例如。 current.Bars
返回[bar1, bar2, bar3]
,previous.Bars
返回[bar1, bar2, bar3]
。
如果我切换两个查询(即将previous
放在current
之前),那么当前的条形与之前的条形相同.Bars。例如。 current.Bars返回[bar4, bar5, bar6]
,previous.Bars
返回[bar4, bar5, bar6]
。
请注意,我100%确定previous.Bars中的基础数据应该与current.Bars不同。即对于[bar4, bar5, bar6]
我应该previous.Bars
而[bar1, bar2, bar3]
<{p}} current.Bars
有人可以解释为什么我得到相同的结果?我怎么解决这个问题?我意识到只有一个查询可能更好。
提前致谢!
PS我正在使用0.8版本
答案 0 :(得分:2)
问题行是.options(contains_eager('Bars'))
。它基本上告诉sqlachemy
该查询包含加载的每个Bars
的所有 foo
。因此,当您访问foo.Bars
时,它不再查询数据库,因为它已从join
获取了那些(过滤的)条并假设它们是完整的{{ 1}}关系
下次运行查询时,sqlalchemy会意识到对象foo.Bars
已经加载(包括其关系Foo
),并且基本上返回它当前在会话中的内容(内存)。
您可以在执行Bars
的查询之前使用session.expunge(current)
从会话中删除对象来解决此问题,以便previous
完全重新加载它,但您必须在此之后要小心使用sqlalchemy
实例,因为它不再是会话的一部分了。
更好:既然你无论如何都需要双方,只需在python方面轻松实现这一分离:
current