0

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

usersgroups映射回他们拥有的资源的模型,例如:

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所有权模型需要调整为拥有uidgid列以外的东西?

4

1 回答 1

0
session.query(Resource).filter(
     Resource.gid.in_(some_user.groups.gid) | (Resource.uid == some_user.uid))
于 2018-08-17T21:37:41.963 回答