Как проверить существование строки в SQLite с Python?

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

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

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

38
задан fx. 13 March 2010 в 21:48
поделиться

3 ответа

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

fetchall упаковывает результаты (обычно несколько строк данных) в список. Поскольку имена уникальны, 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))))))

yields:

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

yields:

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

yields:

There is no component named bar
Component foo found in 1 row(s)
80
ответ дан 27 November 2019 в 03:12
поделиться

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

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

5
ответ дан 27 November 2019 в 03:12
поделиться

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

exist = cursor.fetchone()
if exist is None:
  ... # does not exist
else:
  ... # exists
19
ответ дан 27 November 2019 в 03:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: