两个sqlalchemy查询返回相同的结果,即使它们具有不同的过滤器

时间:2014-03-05 23:23:18

标签: python sqlalchemy

假设我有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版本

1 个答案:

答案 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