SqlAlchemy Core 和简单的 exists 查询

10 投票
1 回答
5600 浏览
提问于 2025-04-17 18:55

我遇到了一个问题,需要用SqlAlchemy Core来检查某个数据是否在表里。

我觉得最好的方法是用exists这个方法,因为它在找到第一个符合条件的项后就会停止搜索。所以,我写了这个查询:

conn = self.db.connect()
query = exists().where(cookie_table.c.cookie_id == cookie_id)
result = conn.execute(query)

但是它出现了这个错误:

StatementError: Not an executable clause (original cause: ArgumentError: Not an
executable clause) 'EXISTS (SELECT * \nFROM cookie \nWHERE cookie.cookie_id = ?)' []

我尝试稍微修改了一下(和select结合),但没有成功。

最后,我想出了另一个解决办法,使用limit(1),这个方法是有效的。

conn = self.db.connect()
query = select([1], cookie_table.c.cookie_id == cookie_id).limit(1)
result = conn.execute(query).fetchone()
return True if result is not None else False

我有两个问题:

如何使用exists方法来完成这个任务?

使用limit的查询效率和使用exists的查询一样吗?

1 个回答

11

根据文档exists是用在Select对象上的,下面是一些示例:

# use on an existing select()
s = select([table.c.col1]).where(table.c.col2==5)
s = exists(s)

# construct a select() at once
exists(['*'], **select_arguments).where(criterion)

# columns argument is optional, generates "EXISTS (SELECT *)"
# by default.
exists().where(table.c.col2==5)

那么你的代码出了什么问题呢?

根据我的理解,EXISTS本身并不是一个指令,所以直接去执行一个exists()会失败,因为它不是一个可以执行的语句。

举个例子,你可以在简单的sqlite控制台试试:

  • EXISTS(SELECT * from t); 会报错
  • SELECT EXISTS(SELECT * FROM t); 会返回0或1,正如预期的那样。

如何解决你的问题?

把你的exists()放在一个select()可执行的语句里:

result = conn.execute(select([exists().where(cookie_table.c.cookie_id == cookie_id)]))

这样应该就能按预期工作了:

>>> print select([exists().where(users.c.name=='test')])
SELECT EXISTS (SELECT *
FROM users
WHERE users.name = :name_1)

那么,你应该使用exists还是limit呢?老实说,我也不知道,甚至不确定答案是否取决于你的数据库引擎……

撰写回答