Peewee中的NOT IN操作符
文档里有说明如何使用 IN
操作符,但是我找不到如何使用 NOT IN
操作符的方法。
如果我用 not <<
,就会出现语法错误。
如果我用 not <FieldName> <<
,结果会变成 WHERE False
,而不是像 WHERE (<FieldName> NOT IN (SELECT ...
这样的子查询。
这是根据文档示例得到的输出。第一个是正确的,第二个和第三个都是错误的。
>>> Tweet.select().where(Tweet.user << a_users).sql()
('SELECT t1."id", t1."user_id", t1."message", t1."created_date", t1."is_published" FROM "tweet" AS t1 WHERE (t1."user_id" IN (SELECT t2."id" FROM "user" AS t2 WHERE (Lower(Substr(t2."username", ?, ?)) = ?)))', [1, 1, 'a'])
>>> Tweet.select().where(not Tweet.user << a_users).sql()
('SELECT t1."id", t1."user_id", t1."message", t1."created_date", t1."is_published" FROM "tweet" AS t1 WHERE ?', [False])
>>> Tweet.select().where(Tweet.user not << a_users).sql()
SyntaxError: invalid syntax
3 个回答
1
这其实和Peewee没什么关系。Peewee只是用了一些Python的运算符来实现自己的功能。<<
通常是一个数字运算符,给它加上逻辑否定是没有意义的。所以not <<
在Python中是无效的语法。
你的第二个例子差不多,但not
只作用于Tweet.user
(因为not
的优先级比<<
高)。加上一些括号,你可以这样写:
Tweet.select().where(not (Tweet.user << a_users)).sql()
不过这仍然不对,正如你发现的那样(读者们:可以看看评论区的讨论)。not
返回的是一个布尔值,这并不是我们想要的,无法正常工作。Peewee把~
运算符重新用来做这个;可以看看@coleifer的回答。
4
我知道这算是“复活帖”,不过这个问题在谷歌上搜索 peewee not in
时是第一个结果,所以我想在这里补充一下:
你还可以使用 not_in
方法,这在文档中有说明:
Tweet.select().where(Tweet.user.not_in(a_users))
对我来说,这种写法比 ~ ... <<
这种写法要清晰很多。
33
简单来说:
Tweet.select().where(Tweet.user.not_in(a_users))
如果你想要稍微不同的意思,比如说“x 不在 y 中”,而不是“x 不在 y 里”,可以用下面的方式:
Tweet.select().where(~(Tweet.user << a_users))