SQLAlchemy递归多对多关系

时间:2010-06-30 12:58:29

标签: sqlalchemy pylons

我有一个案例,我使用一个表来存储用户和组相关的数据。此列称为配置文件。所以,基本上这个表是多对多表,用于一个用户属于多个组或一个组中有多个用户的情况。

我有点困惑如何描述......

以下是该课程的简化演示。

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]

1 个答案:

答案 0 :(得分:4)

首先,我同意Raven的评论,即您应该为UsersGroups使用单独的表格。原因是您可能会获得一些不一致的数据,其中User可能有其他Users作为其users关系,并且您可能在关系树中有周期。

话虽如此,为了使关系工作声明如下:

...
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')
...

另见Specifying Alternate Join Conditions to relationship()文档部分。