如何使用backref' s / back_populate' s设计相同的2个表之间的2个不同的多对多关系

时间:2014-05-13 16:03:11

标签: python sqlalchemy relationship

这是我想要建模的情况:

users,可以归类为riderdriver。每个ride都有riderdriver。我可以想象使用ride对象,我可以在其中调用ride.driverride.rider。但我发现很难在另一个方向上推论它。对于任何用户u,当我致电u.rides时,目前尚不清楚是否应该返回u是驾驶员或骑手的游乐设施。

我也可以单独设置两个关系,以便u.rides_as_driver返回骑行,其中u是一个驱动程序,u.rides_as_rider返回骑行,其中你是骑手。

这是一种很好的方法来模拟我刚才描述的关系吗?

更新

如果这是一个好方法,我如何在SQLAlchemy中实现这一点?特别是,如何在此设计中使用backref?

以下是我的尝试:

class Ride:
    driver = db.Relationship('User', primaryjoin=driver_id==user.id)
    rider =  db.Relationship('User', primaryjoin=rider_id==user.id)
class User:
    rides_as_rider = db.Relationship('Ride', primaryjoin=id==ride.rider_id)
    rides_as_driver = db.Relationship('Ride', primaryjoin=id==ride.driver_id)

1 个答案:

答案 0 :(得分:3)

事实上,您应该使用两个relationship的结论反映出这不仅是表示此连接的好方法, 这是唯一的方式

relationship模型不是远程表,在您的情况下是Ride,而是表之间的连接。 RideUser之间有两个连接,用于每个用户可以在一次骑行中扮演的两个角色。

有关此事实的更多证据,请注意您还有两个relationship面向Ride,朝向User,每个分支对应一个分支。由于你有两个,你还需要不同的backref,每个一个。

但是,你的代码还不够。你应该告诉sqlalchemy“这种关系是那种关系,只是倒退”。事实上,你有四种关系,没有人知道另一种关系的存在。这将表现为Ride.driverUser.rides_as_driver未发生变化的神秘效果。

修复很简单,但是为每个关系添加一个back_populates,sqlalchemy会让它们保持同步:

class Ride:
    driver = db.Relationship('User', primaryjoin=driver_id==user.id, back_populates="rides_as_driver")
    rider =  db.Relationship('User', primaryjoin=rider_id==user.id, back_populates="rides_as_rider")
class User:
    rides_as_rider = db.Relationship('Ride', primaryjoin=id==ride.rider_id, back_populates="rider")
    rides_as_driver = db.Relationship('Ride', primaryjoin=id==ride.driver_id, back_populates="driver")