今日、Pythonのdb-api fetchone vs fetchmany vs fetchallについて同僚と話し合いました。
これらのそれぞれのユースケースは、使用しているdb-apiの実装に依存していると確信していますが、一般的にfetchone vs fetchmany vs fetchallのユースケースは何ですか?
言い換えれば、以下は同等ですか?または、これらのいずれかが他よりも優先されていますか?もしそうなら、どの状況で?
cursor.execute("SELECT id, name FROM `table`")
for i in xrange(cursor.rowcount):
id, name = cursor.fetchone()
print id, name
cursor.execute("SELECT id, name FROM `table`")
result = cursor.fetchmany()
while result:
for id, name in result:
print id, name
result = cursor.fetchmany()
cursor.execute("SELECT id, name FROM `table`")
for id, name in cursor.fetchall():
print id, name
実際には実装に依存すると思いますが、MySQLdbソースを調べることで違いを知ることができます。オプションに応じて、mysqldb fetch *は現在の行セットをメモリまたはサーバー側に保持するため、fetchmany vs fetchoneは(pythonの)メモリに保持するものとdbサーバー側に保持するものを知るための柔軟性を備えています。
PEP 249にはあまり詳細がないので、正確なセマンティクスは実装定義ですが、データベースに応じて物事を最適化するためだと思います。
これらは実装固有です。
テーブルからすべての結果を取得します。これは、テーブルのサイズが小さい場合に機能します。テーブルのサイズが大きい場合、それらの場合、fetchallは失敗します。
ほとんどのメモリを使用します。
クエリがネットワークで実行されると、いくつかの問題が発生する可能性があります。
fetchmanyは、必要な数の結果のみを取得します。結果とプロセスを生成できます。 fetchmanyの実装の簡単なスニペット。
while True:
results = cursor.fetchmany(arraysize)
if not results:
break
for result in results:
yield result
fetchone()
クエリ結果セットの次の行を取得して、単一のTupleを返すか、使用可能なデータがなくなったらNoneを返します。
>>> cur.execute("SELECT * FROM test WHERE id = %s", (3,))
>>> cur.fetchone()
(3, 42, 'bar')
以前のexecute *()の呼び出しで結果セットが生成されなかった場合、または呼び出しがまだ発行されていない場合、ProgrammingErrorが発生します。
fetchmany([size = cursor.arraysize])
クエリ結果の次の行セットを取得し、タプルのリストを返します。使用可能な行がなくなると、空のリストが返されます。
呼び出しごとにフェッチする行の数は、パラメーターによって指定されます。指定されていない場合、カーソルの配列サイズによってフェッチされる行数が決まります。このメソッドは、sizeパラメーターで指定された数の行をフェッチしようとします。指定された行数が利用できないためにこれが不可能な場合、返される行の数は少なくなります。
>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchmany(2)
[(1, 100, "abc'def"), (2, None, 'dada')]
>>> cur.fetchmany(2)
[(3, 42, 'bar')]
>>> cur.fetchmany(2)
[]
以前のexecute *()の呼び出しで結果セットが生成されなかった場合、または呼び出しがまだ発行されていない場合、ProgrammingErrorが発生します。
サイズパラメータにはパフォーマンスに関する考慮事項があることに注意してください。最適なパフォーマンスを得るには、通常、arraysize属性を使用するのが最適です。サイズパラメータを使用する場合、1つのfetchmany()呼び出しから次の呼び出しまで同じ値を保持するのが最適です。
リストアイテム
fetchall()
クエリ結果のすべての(残りの)行を取得し、タプルのリストとして返します。取得するレコードがなくなると、空のリストが返されます。
>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchall()
[(1, 100, "abc'def"), (2, None, 'dada'), (3, 42, 'bar')]
以前のexecute *()の呼び出しで結果セットが生成されなかった場合、または呼び出しがまだ発行されていない場合、ProgrammingErrorが発生します。