Как проверить наличие строки в SQLite с Python? - PullRequest
34 голосов
/ 14 марта 2010

У меня есть курсор с оператором запроса следующим образом:

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

Я хочу проверить наличие компонентов: name и вернуться к переменной python. Как мне это сделать?

Ответы [ 5 ]

77 голосов
/ 14 марта 2010

Поскольку name уникальны, я действительно предпочитаю ваш (ОП) метод использования fetchone или метод Алекса Мартелли с использованием SELECT count(*) вместо моего первоначального предложения использовать fetchall.

fetchall упаковывает результаты (обычно несколько строк данных) в список. Поскольку name s уникальны, fetchall возвращает либо список с одним кортежем в списке (например, [(rowid,),], либо пустой список []. Если вы хотите узнать rowid, тогда используйте fetchall требует, чтобы вы просмотрели список и кортеж, чтобы добраться до rowid.

В этом случае лучше использовать fetchone, поскольку вы получаете только одну строку, (rowid,) или None. Чтобы получить rowid (при условии, что он есть), вам просто нужно выбрать первый элемент кортежа.

Если вас не волнует конкретный rowid, и вы просто хотите знать, что есть хит, тогда вы можете использовать предложение Алекса Мартелли, 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)
18 голосов
/ 14 марта 2010

Я нашел ответ.

exist = cursor.fetchone()
if exist is None:
  ... # does not exist
else:
  ... # exists
5 голосов
/ 14 марта 2010

Как указывают оба существующих ответа (ваш и @ unutbu), хитрость в том, что вам нужно выполнить некоторую сортировку после выполнения SELECT, чтобы проверить, были ли любые результаты для выбора или нет (независимо от того, делаете ли вы это с одной выборкой и проверяете на отсутствие, или с выборочной выборкой и проверяете пустой список), это незначительная разница - учитывая, что вы упоминаете ограничение UNIQUE, которое они ' в основном эквивалентные подходы).

Для очень прямого ответа вы могли бы select count(*) from components where name = ? вместо выбора rowid, если все, что вас волнует, - это наличие заданного значения имени или нет (в отличие от того, какое значение имеет идентификатор строки, если вообще;-). Выполнение этого выбора и извлечение результата дает вам 0, если значение отсутствует, 1, если оно присутствует (другой результат невозможен, учитывая то, что вы упомянули в комментарии об ограничении UNIQUE для столбца name ; -.)

0 голосов
/ 04 мая 2019

Начиная с Python 3.8 и введением выражений присваивания (PEP 572) (оператор :=), мы можем немного изменить предыдущие ответы, захватив результат 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}')
0 голосов
/ 29 сентября 2016

Чтобы сделать его еще короче ...:

row = cursor.fetchone()

if row:
  print "row is present"
else:
  print "row is not present"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...