2010-06-30 4 views
0

J'ai un cas où j'utilise une table pour stocker des données relatives à l'utilisateur et au groupe. Cette colonne est appelée profil. Donc, fondamentalement, cette table est une table plusieurs-à-plusieurs pour les cas où un utilisateur appartient à de nombreux groupes ou il y a beaucoup d'utilisateurs dans un groupe.relation SQLAlchemy récursive plusieurs-à-plusieurs

Je suis un peu confus comment il doit être décrit ...

Voici une présentation simplifiée de la classe.

Entity relationship model

model

user_group_table = Table('user_group', metadata, 
Column('user_id', Integer,ForeignKey('profiles.id', 
    onupdate="CASCADE", ondelete="CASCADE")), 
Column('group_id', Integer, ForeignKey('profiles.id', 
    onupdate="CASCADE", ondelete="CASCADE")) 
) 

class Profile(Base) 
    __tablename__ = 'profiles' 

    id = Column(Integer, autoincrement=True, primary_key=True) 
    name = Column(Unicode(16), unique=True) # This can be either user-/groupname 
    groups = relationship('Profile', secondary=user_group_table, backref = 'users') 
    users = relationship('Profile', secondary=user_group_table, backref = 'groups') 

#Example of the usage: 
user = Profile() 
user.name = 'Peter' 

salesGroup = Profile() 
salesGroup.name = 'Sales' 

user.groups.append(salesGroup) 

salesGroup.users 
>[peter] 
+0

Généralement, avec beaucoup-à-plusieurs, vous voulez 3 tables - une pour chacun des deux objets dans la comparaison, et une troisième qui contient des enregistrements contenant les clés primaires de deux objets qui satisfont la relation. Cela dit, je ne suis pas sûr de bien comprendre la question ... –

Répondre

4

Tout d'abord, je suis d'accord avec le commentaire de Raven que vous devez utiliser des tables séparées pour Users et Groups. La raison en est que vous pourriez obtenir des données incohérentes où pourrait avoir d'autres Users que ses relations users, ainsi que vous pourriez avoir des cycles dans l'arbre des relations.

Cela dit, pour faire le travail de relation déclarer comme suit:

... 
class Profile(Base): 
    __tablename__ = 'profiles' 
    id = Column(Integer, primary_key=True, autoincrement=True) 
    name = Column(Unicode(16), unique=True) # This can be either user-/groupname 
    groups = relationship('Profile', 
       secondary=user_group_table, 
       primaryjoin=user_group_table.c.user_id==id, 
       secondaryjoin=user_group_table.c.group_id==id, 
       backref='users') 
... 

Voir aussi Specifying Alternate Join Conditions to relationship() section de documentation.

+0

Thanks Van En raison du type de logiciel, il est plus facile pour nous de stocker toutes les données dans le même tableau. Cela fait partie des fonctionnalités que certains utilisateurs pourraient utiliser en tant que groupe. Au début, j'étais aussi très méfiant à l'égard de ce modèle, mais comme il semble que le logiciel reste très simplifié, j'ai décidé de tenter le coup. – Heikki

+0

Bonne chance avec ça. Le modèle peut être simple, mais vous devez vous assurer de la qualité des données. – van

Questions connexes