如何在flask-sqlalchemy中实现三方多对多的关系

bac*_*ter 9 python orm sqlalchemy flask flask-sqlalchemy

什么是设计烧瓶sqlalchemy中三对多对多的正确方法?

假设我有用户,团队和角色.用户被分配到团队.分配给团队后,还会在该团队中为用户分配角色.

from myapp import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), unique=True)

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<User(%s)>" % self.name

class Team(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), unique=True)

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Team(%s)>" % self.name

class Role(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), unique=True)

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Role(%s)>" % self.name
Run Code Online (Sandbox Code Playgroud)

为此设计代理表的几种方法都失败了.我认为我误解了文档,因此不想让你迷惑我到目前为止所采取的所有失败的方法.

我想留下一个问题:在flask-sqlalchemy中设计一个三向多对多关系的正确方法是什么.

bac*_*ter 14

经过大量的研究和挖掘,我终于找到了答案.由于我发现许多其他人很难解决这个问题并且找不到完整而明确的答案,我想我可以在这里发布给未来的旅行者.

如果你遇到了这个问题,那么你可能不是真正想要多对多的三方.我以为我是,但我不是.

回顾: 我有用户,团队和角色.如果用户加入团队,他也会在该团队中分配一个角色.

我回到刮板上画了我真正想要的东西:

+---------+---------+---------+
| user_id | team_id | role_id |
+---------+---------+---------+
|       1 |       1 |       1 |
+---------+---------+---------+
Run Code Online (Sandbox Code Playgroud)

然后它开始变得清晰,我不是真的在寻找一个三对多对多,而是一个三向一对多离开第四个模型.

class Membership(db.Model):
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    team_id = db.Column(db.Integer, db.ForeignKey('team.id'), primary_key=True)
    role_id = db.Column(db.Integer, db.ForeignKey('role.id'), primary_key=True)

    db.UniqueConstraint('user_id', 'team_id', 'role_id')
    db.relationship('User', uselist=False, backref='memberships', lazy='dynamic')
    db.relationship('Team', uselist=False, backref='memberships', lazy='dynamic')
    db.relationship('Role', uselist=False, backref='memberships', lazy='dynamic')

    def __init__(self, user, team, role):
        self.user_id = user.id
        self.team_id = team.id
        self.role_id = role.id

    def __repr__(self):
        return "<Membership(%s)>"
Run Code Online (Sandbox Code Playgroud)

案例42:这正是我一直在寻找的答案 - 我刚刚问了错误的问题.

  • 有兴趣了解如何添加/修改/删除此*三元*关系中的项目 (5认同)