SqlAlchemy并通过双重关系为我的用户获取角色

时间:2013-08-08 11:20:13

标签: python sqlalchemy

我有三张桌子:

profile
  id, int, pk
  name...

role
  id, int, pk
  name
  ...

profilerole
  role_id     int, pk, foreign_key to role.id
  profile_id  int, pk, foreign_key to role.id

我想写一些东西来加载角色信息,我现在有以下个人资料类:

class profile(Base):
    __tablename__ = 'profile'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    password = Column(String)
    email = Column(String)
    enabled = Column(Boolean)
    verified = Column(Boolean)
    deleted = Column(Boolean)

    # this is the line I need help with...
    roles = relationship('roleprofile'
                 primaryjoin="and_(profile.id==roleprofile.id",
                 backref="profile")

上面的一行将为我提供表roleprofile中的角色信息,但我希望它给我的是role表中的角色。

这可能吗?我将如何去做?

更新

使用这种关系:

roles = relationship('role', secondary=roleprofile, backref='profiles')

为什么要定义它:

roleprofiles = Table('roleprofile', Base.metadata,
                  Column('role_id', Integer, ForeignKey('role.id')),
                  Column('profile_id', Integer, ForeignKey('profile.id'))
                  )

如果没有:

class roleprofile(Base):
    __tablename__ = 'roleprofile'

    role_id = Column(Integer, ForeignKey('role.id'), primary_key=True)
    profile_id = Column(Integer, ForeignKey('profile.id'), primary_key=True)

    def __init__(self, name, created_by, last_updated_by, created=datetime.now(), last_updated=datetime.now()):
        self.name = name
        self.created = created
        self.created_by = created_by
        self.last_updated = last_updated
        self.last_updated_by = last_updated_by

在已经定义时使用roleprofile定义关联时,我得到一个错误,所以它们似乎是相同的但只有第一个有效。该课程给出了错误:

TypeError: __init__() takes at least 4 arguments (1 given)

1 个答案:

答案 0 :(得分:2)

这是SQLAlchemy中易于表达的标准多对多关系:http://docs.sqlalchemy.org/en/rel_0_8/orm/relationships.html#many-to-many

您需要将中间表指定为secondary的{​​{1}}参数。在最简单的情况下,不需要提供显式relationship,SQLAlchemy可以自己从元数据中找出连接条件。

primaryjoin

如果已经为中间表定义了声明性模型,则可以将profile_roles = Table('profilerole', Base.metadata, Column('role_id', Integer, ForeignKey('role.id'), primary_key=True), Column('profile_id', Integer, ForeignKey('profile.id')), primary_key=True) class Profile(Base): ... roles = relationship('Role', secondary=profile_roles, backref='profiles') 指定为<modelclass>.__table__参数,而不是使用SQLAlchemy核心。但也许你不需要这个表的完整模型:SQLAlchemy知道它需要用secondary创建它,并且可以通过集合界面操纵关系。