如何用Python检查SQLite中行的存在性?

49 投票
7 回答
116492 浏览
提问于 2025-04-15 20:24

我有一个光标,里面有这样的查询语句:

cursor.execute("select rowid from components where name = ?", (name,))

我想检查一下是否存在一些组件:名字,并把结果返回给一个Python变量。我该怎么做呢?

相关问题:

7 个回答

6

正如你和@unutbu的回答所提到的,关键在于你需要在执行完SELECT之后,进行某种方式的数据获取,以检查是否有查询结果。这可以是单次获取并检查是否为空,或者获取所有结果并检查列表是否为空,这两种方式其实差别不大。考虑到你提到的UNIQUE约束,这两种方法基本上是等价的。

如果你只关心某个名字是否存在,而不在乎它的行号,你可以直接使用select count(*) from components where name = ?,而不是选择rowid。执行这个查询后,如果结果是0,说明这个名字不存在;如果是1,说明这个名字存在(根据你在评论中提到的UNIQUE约束,其他结果是不可能的)。

22

我找到了答案。

exist = cursor.fetchone()
if exist is None:
  ... # does not exist
else:
  ... # exists
98

因为name是唯一的,所以我更喜欢你(提问者)使用fetchone的方法,或者Alex Martelli使用SELECT count(*)的方法,而不是我最初建议的使用fetchall

fetchall会把结果(通常是多行数据)放在一个列表里。由于name是唯一的,fetchall返回的结果要么是一个只包含一个元组的列表(比如[(rowid,),]),要么是一个空列表[]。如果你想知道rowid,那么使用fetchall就需要在这个列表和元组里翻找,才能找到rowid

在这种情况下,使用fetchone更好,因为你只会得到一行数据,可能是(rowid,)或者None。要获取rowid(如果存在的话),你只需要取出元组的第一个元素。

如果你不在乎具体的rowid,只想知道是否有结果,那么你可以使用Alex Martelli的建议,SELECT count(*),这会返回(1,)或者(0,)

下面是一些示例代码:

首先是一些基础代码,用来设置一个简单的sqlite表:

import sqlite3
connection = sqlite3.connect(':memory:')
cursor=connection.cursor()
cursor.execute('create table components (rowid int,name varchar(50))')    
cursor.execute('insert into components values(?,?)', (1,'foo',))

使用fetchall

for name in ('bar','foo'): 
    cursor.execute("SELECT rowid FROM components WHERE name = ?", (name,))
    data=cursor.fetchall()
    if len(data)==0:
        print('There is no component named %s'%name)
    else:
        print('Component %s found with rowids %s'%(name,','.join(map(str, next(zip(*data))))))

结果是:

There is no component named bar
Component foo found with rowids 1

使用fetchone

for name in ('bar','foo'): 
    cursor.execute("SELECT rowid FROM components WHERE name = ?", (name,))
    data=cursor.fetchone()
    if data is None:
        print('There is no component named %s'%name)
    else:
        print('Component %s found with rowid %s'%(name,data[0]))

结果是:

There is no component named bar
Component foo found with rowid 1

使用SELECT count(*)

for name in ('bar','foo'): 
    cursor.execute("SELECT count(*) FROM components WHERE name = ?", (name,))
    data=cursor.fetchone()[0]
    if data==0:
        print('There is no component named %s'%name)
    else:
        print('Component %s found in %s row(s)'%(name,data))

结果是:

There is no component named bar
Component foo found in 1 row(s)

撰写回答