我有以下型号。用户具有多个角色,角色可以拥有许多权限。我无法弄清楚如何查询以获得我想要的东西。
user_role = db.Table(
'user_role',
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
db.UniqueConstraint('user_id', 'role_id')
)
role_permission = db.Table(
'role_permission',
db.Column('permission_id', db.Integer, db.ForeignKey('permission.id')),
db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
db.UniqueConstraint('permission_id', 'role_id')
)
class Role(Base):
__tablename__ = 'role'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True, nullable=False)
class Permission(Base):
__tablename__ = 'permission'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
roles = db.relation(Role, secondary=role_permission, backref=db.backref('permissions'))
class User(Base, UserMixin):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(60), unique=True, nullable=False)
password_hash = db.Column(db.String(80), nullable=False)
roles = db.relation(Role, secondary=user_role, backref=db.backref('users'))
我想获得分配给用户的所有权限的列表(最好是唯一的),但我似乎无法弄清楚如何做到这一点。
我可以通过在用户模型中创建生成器来获取列表:
def get_all_permissions(self):
for role in self.roles:
for perm in role.permissions:
yield perm
但我希望能够在一次查询中做到这一点。
答案 0 :(得分:1)
好吧,要获取权限列表,请尝试以下方法:
permissions = session.query(Permission).\
join(Role).join(User).filter(User.username='MisterX').all()
或过滤所需的任何内容。要使权限唯一,您可以使用group by:
permissions = session.query(Permission.id, Permission.name).join(Role).join(User).\
filter(User.username='MisterX').group_by(Permission.id).all()
或者,如果没有特殊查询,请使用声明性扩展,如果可以:
permissions = User.roles.permissions
这有帮助吗?
答案 1 :(得分:1)
可能无法正确识别关联表,因为您未指定元数据参数。这个脚本适合我:
#!/bin/python
from sqlalchemy import Table
from sqlalchemy import Integer, String, ForeignKey, create_engine, Column, PrimaryKeyConstraint
from sqlalchemy.orm import relationship, backref, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()
user_role = Table(
'user_role',
Base.metadata,
Column('user_id', Integer, ForeignKey('users.id')),
Column('role_id', Integer, ForeignKey('roles.id')),
PrimaryKeyConstraint('user_id', 'role_id')
)
role_permission = Table(
'role_permission',
Base.metadata,
Column('permission_id', Integer, ForeignKey('permissions.id')),
Column('role_id', Integer, ForeignKey('roles.id')),
PrimaryKeyConstraint('permission_id', 'role_id')
)
class Role(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String(100), unique=True, nullable=False)
class Permission(Base):
__tablename__ = 'permissions'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)
roles = relationship("Role", secondary=role_permission, backref=backref('permissions'))
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String(60), unique=True, nullable=False)
password_hash = Column(String(80), nullable=False)
roles = relationship("Role", secondary=user_role, backref=backref('users'))
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
u = User(username="user", password_hash="secret")
r1 = Role(name="Role 1")
session.add(r1)
r2 = Role(name="Role 2")
session.add(r2)
p1 = Permission(name="Permission 1")
p2 = Permission(name="Permission 2")
p3 = Permission(name="Permission 3")
r1.permissions.append(p1)
r1.permissions.append(p2)
r2.permissions.append(p2)
r2.permissions.append(p3)
u.roles.append(r1)
u.roles.append(r2)
session.add(u)
for perm in session.query(Permission).join(Role, Permission.roles).\
join(User, Role.users).filter(User.username=="user").distict()all():
print(perm.name)
答案 2 :(得分:0)
如果您已将User对象与权限和角色一起加载到内存中,则代码应该快速执行,无需转到数据库。
否则,此查询应该有效:
user_id = 789
permissions = (db.session.query(Permission)
.join(Role, Permission.roles)
.join(User, Role.users)
.filter(User.id == user_id)
).distinct()
#print(permissions)
for perm in permissions:
print(perm)