次のように、クエリステートメントにカーソルがあります。
cursor.execute("select rowid from components where name = ?", (name,))
コンポーネントの存在を確認したい:名前とpython変数に戻ります。どうすればよいですか?
name
sは一意であるため、fetchone
を使用するという最初の提案よりも、fetchall
を使用する(OPの)方法またはSELECT count(*)
を使用するAlex Martelliの方法をお勧めします] _。
fetchall
は、結果(通常は複数行のデータ)をリストにラップします。 name
sは一意であるため、fetchall
は、リストにタプルを1つだけ含むリストを返します(例:[(rowid,),]
または空のリスト[]
。 rowid
を知っている場合、fetchall
を使用するには、リストを掘り下げてrowid
にアクセスする必要があります。
(rowid,)
またはfetchone
の1行のみを取得するため、この場合はNone
を使用することをお勧めします。 rowid
(ある場合)を取得するには、タプルの最初の要素を選択するだけです。
特定のrowid
を気にせず、ヒットがあることだけを知りたい場合は、Alex Martelliの提案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)
答えを見つけました。
exist = cursor.fetchone()
if exist is None:
... # does not exist
else:
... # exists
既存の回答(あなた自身と@unutbuの両方)が指摘しているように、トリックは、SELECT
を実行した後にsome並べ替えを行う必要があるということです。選択に対する結果であるかどうか(単一のフェッチで実行して何もチェックしないか、全フェッチで空のリストをチェックするかは、UNIQUE
制約は基本的に同等のアプローチです)。
非常に直接的な答えとして、rowid
を選択するのではなく、select count(*) from components where name = ?
を使用できます。nameに指定された値が存在するかどうか(反対に、どの行を気にするかもしあれば、id ;-)。この選択を実行し、結果を取得すると、0
値が存在しない場合、1
存在する場合(列UNIQUE
;-のname
制約についてのコメントで述べたことを考えると、他の結果は得られません)。
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}')