1

我有三张桌子:

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

使用roleprofilewhen already defined 定义关联时出现错误,因此它们似乎相同,但只有第一个有效。该课程给了我错误:

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

1 回答 1

2

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

您需要将中间表指定secondaryrelationship. 在最简单的情况下,不需要提供显式primaryjoin,SQLAlchemy 可以自己从元数据中找出连接条件。

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__secondary参数而不是使用 SQLAlchemy 核心。但也许你无论如何都不需要这个表的完整模型:SQLAlchemy 知道它需要用 来创建它metadata.create_all,并且可以通过集合接口来操作关系。

于 2013-08-08T11:28:54.547 回答