A 在 Postgres 数据库中有几个表:
users
(系统中的用户)groups
(组用户可以是其中的一部分)group_memberships
(组和用户的多对多映射)resources
(用户想要访问的对象)
如果用户拥有资源或资源归其组所有,则用户可以访问资源。目前,这是通过表中的uid
(用户 ID)和gid
(组 ID)外键列实现的resources
。我已经使用 group_memberships 表作为辅助表在用户和组之间建立了映射:
GroupMembership = Table('group_memberships', Base.metadata,
Column('gid', Integer, ForeignKey('users.uid'), primary_key=True),
Column('uid', Integer, ForeignKey('groups.gid'), primary_key=True))
Group.users = relationship(User, secondary=GroupMembership, lazy=True)
User.groups = relationship(Group, secondary=GroupMembership, lazy=True)
资源由用户或组拥有:
class Resource(Base):
# ...
uid = Column(Integer, ForeignKey('users.uid'), nullable=True)
gid = Column(Integer, ForeignKey('groups.gid'), nullable=True)
# ...
users
并groups
映射回他们拥有的资源的模型,例如:
class User(Base):
# ...
resources = relationship('Resource', backref='user', lazy=True, viewonly=True)
# ...
目前,如果我想查询用户可用的所有资源,我会结合 中的所有可用资源user.resources
,然后遍历所有用户的组并添加这些资源:
resources = user.resources + [r for group in user.groups for r in group.resources]
不过,我想要的是在数据库中执行此映射,而不是遍历所有组。看起来这应该很简单,但我不确定我对 SQLAlchemy 文档的理解是否足以完全映射出来。本质上,我正在寻找的东西相当于 SQL 查询,例如具有以下功能的用户uid=1
:
SELECT * FROM resources
WHERE
uid=1 OR
gid in (SELECT gid FROM group_memberships WHERE uid=1)
有什么想法我可以如何将它变成一个sqlalchemy.orm.relationship
?也许我的resources
所有权模型需要调整为拥有uid
和gid
列以外的东西?