How to check the existence of a row in SQLite with Python?

Question:

I have the cursor with the query statement as follows:

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

I want to check for the existence of the components: name and return to a python variable.
How do I do that?

Asked By: fx.

||

Answers:

Since the names are unique, I really favor your (the OP’s) method of using fetchone or Alex Martelli’s method of using SELECT count(*) over my initial suggestion of using fetchall.

fetchall wraps the results (typically multiple rows of data) in a list. Since the names are unique, fetchall returns either a list with just one tuple in the list (e.g. [(rowid,),] or an empty list []. If you desire to know the rowid, then using fetchall requires you to burrow through the list and tuple to get to the rowid.

Using fetchone is better in this case since you get just one row, (rowid,) or None.
To get at the rowid (provided there is one) you just have to pick off the first element of the tuple.

If you don’t care about the particular rowid and you just want to know there is a hit,
then you could use Alex Martelli’s suggestion, SELECT count(*), which would return either (1,) or (0,).

Here is some example code:

First some boiler-plate code to setup a toy sqlite table:

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',))

Using 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))))))

yields:

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

Using 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]))

yields:

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

Using 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))

yields:

There is no component named bar
Component foo found in 1 row(s)
Answered By: unutbu

I have found the answer.

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

As both existing answers (your own and @unutbu’s) point out, the trick is that you do need to do some sort of fetching, after executing the SELECT, to check whether there have been any results to the select or not (whether you do it with a single fetch and check for none, or a fetch-all and check for an empty list, is a marginal difference — given that you mention a UNIQUE constraint they’re basically equivalent approaches).

For a very direct answer, you could select count(*) from components where name = ?, rather than selecting rowid, if all you care is whether the given value for name is present or not (as opposed to, caring about what row id it’s on, if at all;-). Executing this select, and fetching the result, gives you 0 if the value is absent, 1 if it’s present (no other result is possible given what you mentioned in a comment about the UNIQUE constraint on column name;-).

Answered By: Alex Martelli

To make it even shorter…:

row = cursor.fetchone()

if row:
  print "row is present"
else:
  print "row is not present"
Answered By: joe_evans

Starting Python 3.8, and the introduction of assignment expressions (PEP 572) (:= operator), we can slightly modify previous answers by capturing the result of cursor.fetchone() within the condition check and re-use it to extract the result content:

# 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}')
Answered By: Xavier Guihot

The reason mine was showing the "Lock" message was actually due to me having opened an SQLite3 IDE on my Windows and that was the reason it was locked. I assume I was playing around with the DB within the IDE and hadn’t saved the changes and therefor a lock was placed.

This is what worked for me

exist = conn.execute("select rowid from rowid where name = ?", (name,)).fetchone()
if exist is None:
    print("Doesn't exist")
else:
    print("Yep exists")
Answered By: Aadil Faizal
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.