gpt4 book ai didi

python - Sqlalchemy使用orm选择所有不存在连接的mysql

转载 作者:行者123 更新时间:2023-11-28 22:41:22 24 4
gpt4 key购买 nike

我们有两个表:用户和权限

我们要选择所有没有“ guest ”权限的用户。现在,用户可以拥有多个权限(不仅仅是 1 个),所以简单地查询 !"guest"是行不通的。这是我们的查询现在的样子:

query = session.query(Users).join(Permission, and_(
Permission.userId == theUser.uid, Permission.deviceId== theDevice.uid))
query.join(Permission).filter(~exists().where(and_(Permission.level==SqlConstants.PermissionLevels.GUEST, Users.uid == Permission.userId)))

我不确定第一行中的连接是否与我们遇到的问题相关,但我们正在使用它,所以我将它包括在这里。 (如果它不相关,我会编辑它。)

以上返回以下异常:

returned no FROM clauses due to auto-correlation; specify correlate(<tables>) to control correlation manually.

我从以下 SO 帖子中收集了这种模式: Using NOT EXISTS clause in sqlalchemy ORM query

以及来自 sqlalchemy 文档(关于不存在的内容很浅): http://docs.sqlalchemy.org/en/rel_1_0/orm/query.html

我不清楚自己做错了什么,也不清楚是否有更好的方法。

最佳答案

我不确定我是否理解您的问题,主要是因为我想出的解决方案非常简单。我会试一试,无论如何我希望它能以某种方式帮助你。

我能够轻松地重现您在使用 exists 时遇到的异常。我认为这是因为在 where 参数中,您在 join 中混合了两个表的列。如果您或多或少像这样重写它,它不会给出异常,

sq = session.query(Users.pk).join(Permission).filter(Permission.level==SqlConstants.PermissionLevels.GUEST)
q = session.query(Users).join(Permission).filter(~sq.exists())

但是它不起作用,因为一旦在 Permission 中有 1 个寄存器具有 GUEST 级别,查询将不会给出任何结果。

但为什么不这样重写呢?

sq = session.query(Users.pk).join(Permission).filter(Permission.level==SqlConstants.PermissionLevels.GUEST)
q = session.query(Users).filter(~Users.pk.in_(sq))

在我的试验中,如果我正确理解了你的问题,它就会起作用。

仅供引用,这是我使用的玩具示例,其中表 A 对应于 UsersB 对应于 Permission,而 B.attr 将存储权限级别。

In [2]:

class A(Base):
__tablename__ = 'A'

pk = Column('pk', Integer, primary_key=True)
name = Column('name', String)


class B(Base):
__tablename__ = 'B'

pk = Column('pk', Integer, primary_key=True)
fk = Column('fk', Integer, ForeignKey('A.pk'))
attr = Column('attr', Integer)

a = relationship("A", backref='B')

这是我插入的数据,

In [4]:

q = session.query(B)
print(q)
for x in q.all():
print(x.pk, x.fk, x.attr)

q = session.query(A)
print(q)
for x in q.all():
print(x.pk, x.name)

SELECT "B".pk AS "B_pk", "B".fk AS "B_fk", "B".attr AS "B_attr"
FROM "B"
1 1 1
2 1 2
3 2 0
4 2 4
5 1 4
SELECT "A".pk AS "A_pk", "A".name AS "A_name"
FROM "A"
1 one
2 two
3 three

这是查询的结果,

In [16]:

from sqlalchemy import exists, and_, tuple_
sq = session.query(A.pk).join(B).filter(B.attr==2)
print(sq)
q = session.query(A).filter(~A.pk.in_(sq))
print(q)

for x in q.all():
print(x.pk, x.name)
SELECT "A".pk AS "A_pk"
FROM "A" JOIN "B" ON "A".pk = "B".fk
WHERE "B".attr = :attr_1
SELECT "A".pk AS "A_pk", "A".name AS "A_name"
FROM "A"
WHERE "A".pk NOT IN (SELECT "A".pk AS "A_pk"
FROM "A" JOIN "B" ON "A".pk = "B".fk
WHERE "B".attr = :attr_1)
2 two
3 three

希望对您有所帮助!

关于python - Sqlalchemy使用orm选择所有不存在连接的mysql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32658805/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com