Python 与「;“跳跃”;通过SqlAlchemy中的M2M关系(用户->;角色->;权限)
我试图建立一个非常典型的权限结构模型,其中Python 与「;“跳跃”;通过SqlAlchemy中的M2M关系(用户->;角色->;权限),python,sqlalchemy,relationship,m2m,Python,Sqlalchemy,Relationship,M2m,我试图建立一个非常典型的权限结构模型,其中用户模型(我网站的人类用户)可以分配给一些角色,而这些角色中的每一个都有一些权限 如果我能从用户直接获得权限的关系,那将非常有帮助。这样,我可以从数据库中获取一个用户(实例),只需执行user.permissions即可获取他的权限,进行一些筛选以检查用户是否具有特定的权限,并将其预加载。。。总之:所有与关系相关的好东西 viewonly关系将非常好。正如Mike Bayer在中提到的那样,我不能向User.permissions写信,因为我们不知道要使
用户
模型(我网站的人类用户)可以分配给一些角色
,而这些角色中的每一个都有一些权限
如果我能从用户
直接获得权限
的关系
,那将非常有帮助。这样,我可以从数据库中获取一个用户(实例),只需执行user.permissions
即可获取他的权限,进行一些筛选以检查用户是否具有特定的权限
,并将其预加载。。。总之:所有与关系相关的好东西
viewonly
关系将非常好。正如Mike Bayer在中提到的那样,我不能向User.permissions
写信,因为我们不知道要使用哪个“角色”或在哪里插入它
我创建了两个中间表:
User -- M2M --> Role(s) -- M2M --> Permission(s)
| ^
+-------- user.permissions -----------+
用户\u角色
通过其主键(ID)将用户
连接到其角色
- 和
角色\u权限
将每个角色
连接到其权限
这是我的表格结构(问题简化了,但即使是完整的版本也非常典型和简单)
我看到这看起来很有希望,但我似乎无法让它发挥作用。老实说,我已经尝试了很多组合,我想说我得到的最远的结果是:
permissions = relationship('Permission',
secondary="""join(User, users_roles,
User.id == users_roles.c.user_id
).join(roles_permissions,
users_roles.c.role_id == roles_permissions.c.role_id
).join(
Permission, roles_permissions.c.permission_id == Permission.id
)""",
viewonly=True,
)
这给了我一个错误:
sqlalchemy.exc.ArgumentError: Relationship User.permissions
could not determine any unambiguous local/remote column pairs
based on join condition and remote_side arguments. Consider
using the remote() annotation to accurately mark those elements
of the join condition that are on the remote side of the relationship.
如有任何提示,将不胜感激。提前感谢。辅助表不应包括相关表本身,而应包括它们之间的关联:
permissions = relationship(
'Permission',
secondary="""join(users_roles, roles_permissions,
users_roles.c.role_id == roles_permissions.c.role_id)""",
viewonly=True,
)
将要联接的表放在次表中会使试图通过次表查找用户
和权限
之间的外键关系的自动化操作变得混乱。OMG。。。小时!!。。。我花了几个小时尝试不同的东西组合!!非常感谢。这里的概念是连接有效地创建了一个关联表吗?@supershot。您可以使用about任意表(存在外键)作为辅助表,无论它是联接、选择或类似操作的结果:。由于SQLA处理重复数据消除实体的方式,即使联接多次生成相同的权限id也不是问题。即使联接多次生成相同的权限id也不是问题。我可以对此进行评估。我创建了一个测试,其中一个用户
属于两个不同的角色,每个角色具有相同的权限,并且在我的用户中。权限
关系中,我只获得一个权限
实例,即使我没有在关系
中指定collection\u class=set
。这让我有点担心(获得重复权限),但不是:这不会发生。。。它工作得很好:+1:
permissions = relationship(
'Permission',
secondary="""join(users_roles, roles_permissions,
users_roles.c.role_id == roles_permissions.c.role_id)""",
viewonly=True,
)