SQLAlchemy&复杂查询

时间:2010-06-02 15:22:53

标签: sql join sqlalchemy python-elixir

我必须为现有应用程序实现ACL。
因此,我将用户 groupmembers 表添加到数据库中。
我通过关联表 groupmembers 用户之间定义了ManyToMany关系。
为了保护应用程序的一些资源(i..e item ),我添加了一个额外的关联表 auth_items ,它应该用作ManyToMany之间关系的关联表 群组/用户 以及特定的 项目

项目包含以下列:

  • user_id - >用户表
  • group_id - >小组表
  • item_id - >项目表

至少设置 user_id group_id 列。因此,可以为组或用户定义特定项的访问权限。

我使用了AssociationProxy来定义用户/组和项目之间的关系。

我现在想要显示用户有权访问的所有项目,我很难做到这一点。使用以下标准:

  • 应显示用户拥有的所有项目(item.owner_id = user.id)
  • 应显示所有公共项目(item.access = public)
  • 应显示用户有权访问的所有项目(auth_item.user_id = user.id)
  • 应显示该用户组有权访问的所有项目。

前三个标准非常简单,但我很难完成第四个标准。

这是我的方法:

clause = and_(item.access == 'public')
if user is not None:
   clause = or_(clause,item.owner == user,item.users.contains(user),item.groups.contains(group for group in user.groups))

第三个标准会产生错误。

item.groups.contains(group for group in user.groups)

我实际上不确定这是否是一个好方法。
过滤多种关系时,最好的方法是什么? 我如何根据另一个列表/关系过滤多种关系?

顺便说一下,我使用的是最新的sqlalchemy(6.0)和elixir版本

感谢您的任何见解。

1 个答案:

答案 0 :(得分:1)

contains()方法用于单项检查。假设您的组表映射到Group类,请尝试以下操作:

item.groups.any(Group.id.in_([group.id for group in user.groups])