web-dev-qa-db-ja.com

Python db-api:fetchone vs fetchmany vs fetchall

今日、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
60
Alex Q

実際には実装に依存すると思いますが、MySQLdbソースを調べることで違いを知ることができます。オプションに応じて、mysqldb fetch *は現在の行セットをメモリまたはサーバー側に保持するため、fetchmany vs fetchoneは(pythonの)メモリに保持するものとdbサーバー側に保持するものを知るための柔軟性を備えています。

PEP 249にはあまり詳細がないので、正確なセマンティクスは実装定義ですが、データベースに応じて物事を最適化するためだと思います。

14

これらは実装固有です。

  • フェッチオール

テーブルからすべての結果を取得します。これは、テーブルのサイズが小さい場合に機能します。テーブルのサイズが大きい場合、それらの場合、fetchallは失敗します。

ほとんどのメモリを使用します。

クエリがネットワークで実行されると、いくつかの問題が発生する可能性があります。

  • たくさん

fetchmanyは、必要な数の結果のみを取得します。結果とプロセスを生成できます。 fetchmanyの実装の簡単なスニペット。

   while True:
    results = cursor.fetchmany(arraysize)
    if not results:
        break
    for result in results:
        yield result
7
Niranjan Sagar

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が発生します。

4
shreesh katti