2014-04-12 10 views
7

Qual è il modo corretto di progettare un three-to-many a tre in flask-sqlalchemy?Come relazionarsi alla relazione molti a molti in flask-sqlalchemy

Presuppongo che io abbia utenti, squadre e ruoli. Gli utenti sono assegnati ai team. Quando viene assegnato a un team, all'utente viene assegnato anche un ruolo all'interno di quel team.

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 

Diversi approcci per progettare una tabella proxy per questo hanno fallito per me. Penso di fraintendere i documenti e quindi non voglio confonderti con tutti gli approcci falliti che ho preso, finora.

Mi piacerebbe lasciarlo con la domanda: qual è il modo corretto di progettare una relazione a tre-molti-a-molti in fiasco-sqlalchemy.

risposta

9

Dopo molte ricerche e ricerche, ho trovato la risposta, finalmente. Dal momento che ho trovato molte parti di altre persone che hanno difficoltà a risolvere questo problema e non sono riuscito a trovare una risposta completa e chiara, ho pensato che avrei potuto postarlo qui per i futuri viaggiatori.

Se hai risposto a questa domanda, potrebbe essere possibile che tu non stia davvero cercando un tre-a-molti a tre. Pensavo di esserlo, ma non lo ero.

Riepilogo: Ho utenti, squadre e ruoli. Se un utente si unisce a una squadra, gli viene assegnato anche un ruolo all'interno di quella squadra.

sono tornato al graffio bordo e ha richiamato quello che volevo:

+---------+---------+---------+ 
| user_id | team_id | role_id | 
+---------+---------+---------+ 
|  1 |  1 |  1 | 
+---------+---------+---------+ 

poi ha cominciato a diventare chiaro per me, che non ero veramente alla ricerca di un tre vie molti-a -molti, ma piuttosto per un tre-uno-a-molti in partenza da un quarto modello.

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)>" 

Caso di 42: Questo è esattamente la risposta che cercavo - ho appena fatto la domanda sbagliata.

+2

sarebbe interessato a sapere come si aggiungono/modificano/eliminano elementi in questa relazione * ternaria * – van

+0

mi sei sopravvissuto da una ricerca di lunga data. Grazie :) – CoderInNetwork