У меня есть курсор с оператором запроса следующим образом:
cursor.execute("select rowid from components where name = ?", (name,))
Я хочу проверить на существование компонентов: имя и возврат к переменной Python. Как я делаю это?
Поскольку имя
уникально, я действительно предпочитаю ваш (ОП) метод использования 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)
Как указывают оба существующих ответа (ваш собственный и @ unutbu), хитрость в том, что вам действительно нужно выполнить некоторую выборку после выполнения SELECT
, чтобы проверить, есть ли какие-либо результаты для выбора или нет (выполняете ли вы это с помощью одной выборки и проверки на отсутствие или выборки всего и проверки на пустой список, это незначительное различие - - учитывая, что вы упомянули ограничение UNIQUE
, они в основном эквивалентны подходам).
Чтобы получить очень прямой ответ, вы можете выбрать count (*) из компонентов, где name =?
, а не выбирать rowid
, если все, что вам нужно, это то, будет ли заданное значение для имя присутствует или нет (в отличие от того, какой идентификатор строки он включен, если вообще есть ;-). Выполнение этого выбора и получение результата дает вам 0
, если значение отсутствует, 1
, если оно присутствует (другой результат невозможен, учитывая то, что вы упомянули в комментарии к Ограничение UNIQUE
для столбца имя
;-).
Я нашел ответ.
exist = cursor.fetchone()
if exist is None:
... # does not exist
else:
... # exists