SQLAlchemy - 带有额外列的自引用多对多关系

10

我有一个表示用户的模型,我想创建一个表示他们是朋友关系的用户之间的关系。我的功能模型包括关联表和列出所有朋友的方法,看起来像这样:

friendship = db.Table('friend',
    db.Column('id', db.Integer, primary_key=True),
    db.Column('fk_user_from', db.Integer, db.ForeignKey('user.id'), nullable=False),
    db.Column('fk_user_to', db.Integer, db.ForeignKey('user.id'), nullable=False)
)

class User(db.Model):
   ...
   ...
   friends = db.relationship('User',
        secondary=friendship,
        primaryjoin=(friendship.c.fk_user_from==id),
        secondaryjoin=(friendship.c.fk_user_to==id),
        backref = db.backref('friend', lazy = 'dynamic'), 
        lazy = 'dynamic')

    def list_friends(self):
        friendship_union = db.select([
                        friendship.c.fk_user_from, 
                        friendship.c.fk_user_to
                        ]).union(
                            db.select([
                                friendship.c.fk_user_to, 
                                friendship.c.fk_user_from]
                            )
                    ).alias()
        User.all_friends = db.relationship('User',
                       secondary=friendship_union,
                       primaryjoin=User.id==friendship_union.c.fk_user_from,
                       secondaryjoin=User.id==friendship_union.c.fk_user_to,
                       viewonly=True) 
        return self.all_friends
问题在于我需要实现在确认之前请求添加好友和状态挂起(就像你从Facebook中知道的那样),因此需要在好友表中添加一个额外的列。根据SQLAlchemy教程,我应该创建一个Association Object,但如何使它再次自引用呢?
或者,我是否可以将此列添加到当前的好友表中,并以某种方式访问和更改状态值?
谢谢。
2个回答

8

您只需要在您的表中添加primaryjoin,同时在Friendship表中制作两个外键‘primary_key’。您还需要将Friendship定义为一个类。

class Friendship(db.Model):
    __tablename__ = 'friend'
    fk_user_from = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    fk_user_to = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    extra_field = db.Column(db.Integer)


class User (db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    user_to = db.relationship('Friendship',backref='to', primaryjoin=id==Friendship.fk_user_to)
    user_from = db.relationship('Friendship',backref='from', primaryjoin=id==Friendship.fk_user_from )

添加好友需要定义"Friendship",例如:

friend = Friendship(extra_field=0 , to=me , from=my_friend)

我已经用同样的方法解决了这个问题,但还是谢谢你的回答 :) 我接受了。 - skornos
显然,最后一行不起作用。我必须这样做friend = Friendship(extra_field=0 , fk_user_to=me , fk_user_from=my_friend) - Anh Pham
对我来说,这引发了 sqlalchemy.exc.AmbiguousForeignKeysError: 无法确定连接...表之间存在多个外键约束关系。请明确指定此连接的 'onclause'。 - ajwood

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接