如何使用Python检查SQLite中是否存在行?

如何使用Python检查SQLite中是否存在行?,python,sql,sqlite,Python,Sql,Sqlite,我将游标与查询语句放在一起,如下所示: cursor.execute("select rowid from components where name = ?", (name,)) 我想检查组件是否存在:name并返回一个python变量。 如何做到这一点?由于名称是唯一的,我非常喜欢OP使用fetchone的方法或Alex Martelli使用SELECT count*的方法,而不是我最初建议使用fetchall的方法 fetchall通常将结果包装为列表中的多行数据。由于名称是唯一的,fe

我将游标与查询语句放在一起,如下所示:

cursor.execute("select rowid from components where name = ?", (name,))
我想检查组件是否存在:name并返回一个python变量。 如何做到这一点?

由于名称是唯一的,我非常喜欢OP使用fetchone的方法或Alex Martelli使用SELECT count*的方法,而不是我最初建议使用fetchall的方法

fetchall通常将结果包装为列表中的多行数据。由于名称是唯一的,fetchall返回列表中只有一个元组的列表,例如[rowid,,]或空列表[]。如果您想知道rowid,那么使用fetchall需要在列表和元组中钻研以获得rowid

在这种情况下,使用fetchone更好,因为您只获得一行、rowid或None。 要获得提供的rowid,只需从元组的第一个元素中选取一个即可

如果你不关心特定的rowid,你只想知道它是否成功, 然后您可以使用Alex Martelli的建议,选择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:

收益率:

There is no component named bar
Component foo found with rowids 1
There is no component named bar
Component foo found with rowid 1
使用fetchone:

收益率:

There is no component named bar
Component foo found with rowids 1
There is no component named bar
Component foo found with rowid 1
使用SELECT count*:

收益率:

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

我找到了答案

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

正如您自己和@unutbu的现有答案所指出的,诀窍是您确实需要在执行SELECT之后执行某种类型的获取,以检查SELECT是否有任何结果,无论您是使用单个获取并检查无,还是使用全部获取并检查空列表,这是一个边际差异——如果你提到一个独特的约束,它们基本上是等价的方法


对于一个非常直接的答案,您可以从name=?的组件中选择count*,而不是选择rowid,如果您关心的只是name的给定值是否存在,而不是它的行id是什么,如果有的话;-。执行此选择并获取结果,如果该值不存在,则为0;如果该值存在,则为1。如果您在关于列名的唯一约束的注释中提到,则无法获得其他结果;-

让它变得更短…:

row = cursor.fetchone()

if row:
  print "row is present"
else:
  print "row is not present"
从Python 3.8开始,引入:=运算符,我们可以通过在条件检查中捕获cursor.fetchone的结果来稍微修改以前的答案,并重新使用它来提取结果内容:

# cursor.execute("SELECT rowid FROM components WHERE name = ?", (name,))
if item := cursor.fetchone():
  print(f'Component {name} found with rowid {item[0]}')
else:
  print(f'There is no component named {name}')

我显示锁定消息的原因实际上是因为我在Windows上打开了一个SQLite3 IDE,这就是它被锁定的原因。我假设我在IDE中玩弄DB,没有保存更改,因此设置了锁。

是否要检查它是否为NULL或该列是否存在于架构中?否,列名是唯一的,因此我要选择具有该名称的组件,如果它存在或不存在。抱歉,我遗漏了一些细节如果您找到了解决方案,您应该选择一个答案将此问题标记为已回答。最好是其他人的答案为你指明了正确的方向。嗨,亚历克斯,事实上,我想检查一下它是否存在,并获取rowid。所以,这就是为什么我把rowid放在select语句中。您的解决方案运行得非常好,但如果它存在,我必须进行另一次选择以获得结果。你能举一个例子,我可以用一些代码进行检查,以便进行比较吗?获取一个并检查无v.s.获取全部并检查为空抱歉,我是python新手sqlite3@fx,如果您需要rowid,那么您的自我回答中的代码很好,基本上与unutbu相同,并对if数据进行测试:检查非空列表-无需进行任何深入比较。hi unutbu,在对数据赋值之后,您能更清楚地了解python语句吗?我是Pythonhowever新手,“createtablecomponents”中的“name”列我有唯一的属性,这也很重要。谢谢分享代码。@cᴏʟᴅsᴘᴇᴇᴅ: Python3中的sqlite3行为与Python2中的行为相同。事实上,它适用于任何兼容的数据库适配器。zip在Python2中返回一个列表,但在Python3中返回一个zip对象。因此,zip*数据[0]将类似于Python3中的nextzip*数据。对于这里发布的代码,这是Python3所需的唯一更改。另外,请注意聚合函数将始终返回元组。例如,fetchonemincol where false将返回None,fetchallmincol where false将返回[None,]我首先通过执行cursor.executeSELECT*从MyTable中选择此答案与问题无关
# cursor.execute("SELECT rowid FROM components WHERE name = ?", (name,))
if item := cursor.fetchone():
  print(f'Component {name} found with rowid {item[0]}')
else:
  print(f'There is no component named {name}')