2

我希望能够通过 SQLAlchemy 中的多个多对多关系进行查询。

我有用户,它们与组相关联,组与角色相关联。所有关联都是多对多的。我想通过组获取与用户关联的角色列表。

这是我的条纹模型:

class User(Model):
    id = Column(Integer)
    groups = relationship('Group', secondary=user_group)

class Group(Model):
    id = Column(Integer)
    roles = relationship('Role', secondary=role_group)

class Role(Model):
    id = Column(Integer)

我对将使用什么 SQL 有一个粗略的了解:

select distinct role.* from role, role_group
where role.id = role_group.role_id
  and role_group.group_id in 
    (select "group".id from "group", user_group 
     WHERE user_group.user_id = 1 
       and "group".id = user_group."group.id")

但是我很难弄清楚如何将其转换为 SQLAlchemy ......而且我不确定这里的 SQL 是否是最好的方法。

4

2 回答 2

3

尝试这个

s = Session()
s.query(Role).join(User.groups).join(Group.roles).filter(User.id==1).all()

它将生成以下 sql 查询

SELECT role.id AS role_id 
FROM user
JOIN user_group AS user_group_1 ON user.id = user_group_1.user_id
JOIN "group" ON "group".id = user_group_1.group_id
JOIN role_group AS role_group_1 ON "group".id = role_group_1.group_id
JOIN role ON role.id = role_group_1.role_id 
WHERE user.id = 1;

但是 sqlalchemy 只会返回不同的角色(如果您要查询 Role.id 那么 sqlalchemy 将返回 sql 查询实际返回的内容)。

于 2013-07-17T17:35:56.000 回答
0

我确实找到了我自己的问题的解决方案,它会产生接近我正在寻找的 SQL。但是,我相信 zaquest 的答案要好得多,并且会改用它。这只是为了后代。

这是我提出的查询:

s = Session()
s.query(Role).join(Role.groups).filter(
        Group.id.in_(s.query(Group.id).join(User.groups)
                .filter(User.id == self.id)))

这将生成以下 SQL

SELECT role.id AS role_id
FROM role JOIN role_group AS role_group_1 ON role.id = role_group_1.role_id 
JOIN "group" ON "group".id = role_group_1.group_id 
WHERE "group".id IN 
  (SELECT "group".id AS group_id 
   FROM "user" JOIN user_group AS user_group_1 ON "user".id = user_group_1.user_id 
   JOIN "group" ON "group".id = user_group_1."group.id" 
   WHERE "user".id = :id_1)

这类似于我正在寻找的 SQL。我忘记的关键是我可以使用另一个查询作为inSQLAlchemy 中运算符的一部分。

于 2013-07-18T04:58:18.213 回答