在SQLAlchemy ORM查询中如何使用NOT IN子句

92

我该如何将以下的mysql查询语句转换为SQLAlchemy代码?

SELECT * FROM `table_a` ta, `table_b` tb where 1
AND ta.id = tb.id
AND ta.id not in (select id from `table_c`)

到目前为止,我在使用SQLAlchemy方面的内容如下:

query = session.query(table_a, table_b)
query = query.filter(table_a.id == table_b.id)
3个回答

120

ORM内部描述了not_in()运算符(之前是notin_()),因此您可以这样说:

query = query.filter(table_a.id.not_in(subquery))
#                               ^^^^^^

官方文档中介绍:

继承自ColumnOperatorsColumnOperators.not_in()方法实现了 NOT IN 运算符。

这相当于使用否定操作符和ColumnOperators.in_(),即 ~x.in_(y)。

注意:1.4 版本说明

not_in() 运算符从之前的版本 notin_() 重新命名。旧名称仍然可用于向后兼容。

所以在某些情况下,您可能会发现 notin_()


17
简单的列表也可以用来代替子查询。即 notin_([42, 43, 44, 45]) - tandy
1
在1.4中更名为not_in()。https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.ColumnOperators.not_in - user1023102
版本1.3.6 notin_() 可以使用了! - Jonnathan Carrasco

81

试试这个:

subquery = session.query(table_c.id)
query = query.filter(~table_a.id.in_(subquery))
注意:table_atable_btable_c 应该被映射为类,而不是 Table 实例。

你好。在这个例子中,我该如何将 table_a 和 table_b 进行连接? - chrizonline
我假设 query 是你上面展示的查询对象。 - Slava Bacherikov
哦,现在我明白了。最初我迷失了,因为我认为这个例子不是用于连接表的。 - chrizonline
27
这段代码的意思是,在查询table_a时,过滤掉idsubquery中出现过的记录。具体实现方式是使用notin_函数来表示“不在某个集合中”的条件。 - Jonathan Vanasco
如果元素是 None 呢? - rosefun

19

这是完整的代码:

#join table_a and table_b
query = session.query(table_a, table_b)
query = query.filter(table_a.id == table_b.id)

# create subquery
subquery = session.query(table_c.id)
# select all from table_a not in subquery
query = query.filter(~table_a.id.in_(subquery))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接