区别

2013-01-15 20 views
0

我有以下类别:区别

Class User(Base): 
    #user properties 

Class Item(Base): 
    #item properties 

Class User_Item(Base): 
    __tablename__='users_items' 
    id=Column(Integer, primary_key=True) 
    user_id=Column(Integer, ForeignKey('users.id')) 
    item_id=Column(Integer, ForeignKey('items.id')) 
    info=Column(String(20)) 
    user=relationship(User,backref='items',primaryjoin=(User.id==user_id)) 
    item=relationship(Item, backref='users',primaryjoin=(Item.id==item_id)) 

现在就是以下两个查询之间的区别:

result1= session.query(Item).options(joinedload(Item.users)).filter(Item.users.any(user=user1) 

result2=session.query(Item).join(Item.users).filter(Item.users.any(user=user1)) 

为某种原因,第二个看起来很奇怪!假设user1有两个项目,运行result1.count()返回2如预期,但result2.count()返回3!而,len(result2.all())是2!有人可以告诉我,发生了什么事?! :D

+0

你想用你的查询来达到什么目的? – schlamar

+0

例如,在这里我想查找它们映射到user1的所有项目(不使用user1.items !!!),或者更现实的示例是找到所有与'info =“something”'相关的项目。我认为这是我可以实现的第一个查询,但我的问题是第一个和第二个查询是不同的?! – Amin

+0

[我的答案](http://stackoverflow.com/a/14340250/851737)对你的其他问题也可能解决这个问题,... – schlamar

回答

0

joinedload的第一种方法显然不是你想要的,因为它只定义了如何在执行查询后加载item.users(请参阅Relationship Loading Techniques)。

而且随着加入,你应该使用contains而不是any

result3 = session.query(Item).join(Item.users).filter(Item.users.contains(user1)) 

我的猜测是,你的版本any产生每加入结果多行。您可以通过检查生成的SQL来验证这一点(在引擎配置上设置echo=True)。

编辑

你可能定义的多对多的关系错误,这可能是真正的问题。在您的版本User.itemsItem.users都指向User_Item而不是用户或项目,我认为你不知道这一点。

你应该看看Association Object Pattern以及如何可以simplify it

+0

首先,感谢您的答案,但我仍然有两个问题: 1 - 在第一种方法中,我尝试加载Item.users,然后在其上进行查询,因为在加载之前我无法查询用户的属性。它运行良好,有什么具体的原因,为什么它不是我想要的? 2 - 运行您的建议查询,给我一个StatementError! – Amin

+0

你的第一种方法只是比直接访问'user1.items'更复杂的方式(不增加任何真正的好处)。第二种情况下的错误究竟是什么?我仍然认为你想要一个动态的关系,所以你可以使用'User.items'来查询(例如'user1.items.filter(Item.attribute == x).all()')。 – schlamar

+0

更新了答案。 – schlamar