这是我想要建模的情况:
有users
,可以归类为rider
或driver
。每个ride
都有rider
和driver
。我可以想象使用ride
对象,我可以在其中调用ride.driver
或ride.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)
答案 0 :(得分:3)
事实上,您应该使用两个relationship
的结论反映出这不仅是表示此连接的好方法, 这是唯一的方式
relationship
模型不是远程表,在您的情况下是Ride
,而是表之间的连接。 Ride
和User
之间有两个连接,用于每个用户可以在一次骑行中扮演的两个角色。
有关此事实的更多证据,请注意您还有两个relationship
面向Ride
,朝向User
,每个分支对应一个分支。由于你有两个,你还需要不同的backref,每个一个。
但是,你的代码还不够。你应该告诉sqlalchemy
“这种关系是那种关系,只是倒退”。事实上,你有四种关系,没有人知道另一种关系的存在。这将表现为Ride.driver
中User.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")