从Flask Mega Tutorial了解一些Flask-SQLAlchemy内容有些困难。这是代码:
followers = db.Table('followers',
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
)
class User(db.Model):
id = db.Column(db.Integer, primary_key = True)
nickname = db.Column(db.String(64), unique = True)
email = db.Column(db.String(120), index = True, unique = True)
role = db.Column(db.SmallInteger, default = ROLE_USER)
posts = db.relationship('Post', backref = 'author', lazy = 'dynamic')
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime)
followed = db.relationship('User',
secondary = followers,
primaryjoin = (followers.c.follower_id == id),
secondaryjoin = (followers.c.followed_id == id),
backref = db.backref('followers', lazy = 'dynamic'),
lazy = 'dynamic')
def follow(self, user):
if not self.is_following(user):
self.followed.append(user)
return self
def unfollow(self, user):
if self.is_following(user):
self.followed.remove(user)
return self
def is_following(self, user):
return self.followed.filter(followers.c.followed_id == user.id).count() > 0
所以我理解,因为这是一个自引用关系,我们需要一些方法让关联表找出表中哪个用户是跟随者,以及表中哪个用户是被跟踪的用户。 Primaryjoin
和secondaryjoin
完成此任务,但如何实现?
我对primaryjoin
和secondaryjoin
无法理解的三件事情如下:
primaryjoin
和secondaryjoin
检查平等的目的是什么?或者,换句话说,primaryjoin
和secondaryjoin
如何将user.id
添加到关联表中?primaryjoin
和secondaryjoin
都要求user.id
,user.id
会去哪里?这些问题一直让我回到下一章,所以任何答案都非常感激。
答案 0 :(得分:14)
在多对多关系中,primaryjoin表达式描述左表和联结表之间的连接,而secondaryjoin描述联结表和右表之间的连接。换句话说,primaryjoin表达式是,"查找followers表中follower_id为X"的所有行,secondaryjoin表达式说"查找followers表中follow_id为X&#的所有行34;,并将这两者结合起来找到跟随用户X的所有用户,以及用户X后面跟随的所有用户。
这取决于您查询的方向。当您请求user.followers时,它会通过使用primaryjoin查询followers表以查找follow_id == user.id的所有行,并使用other.id == follower_id检索其他用户。当您请求user.followed时,它使用secondaryjoin在followers表中查询follower_id == user.id的所有行,并使用other.id == follow_id检索其他用户。
因为您将其添加到self.followed集合中,告诉SQLAlchemy有人自己正在关注。如果你将它添加到self.followers集合中,你就会做反过来,告诉SQLAlchemy那个用户'是自我的追随者。
参考:SQLAlchemy documentation for specifying alternative join conditions(primaryjoin
和secondaryjoin
)。