80

今日、Python の db-api fetchone と fetchmany と fetchall について同僚と話し合ったところです。

これらのそれぞれの使用例は、使用している db-api の実装に依存していると確信していますが、一般的に、fetchone と fetchmany と 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
4

3 に答える 3

20

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

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

于 2011-03-04T07:10:00.110 に答える
19

公式psycopg2ドキュメントによる

フェッチワン()

クエリ結果セットの次の行を取得して単一のタプルを返すか、使用可能なデータがない場合は None を返します。

>>> cur.execute("SELECT * FROM test WHERE id = %s", (3,))
>>> cur.fetchone()

(3, 42, 'bar')

execute*() への前の呼び出しが結果セットを生成しなかった場合、または呼び出しがまだ発行されていない場合は、ProgrammingError が発生します。

fetchmany([サイズ=cursor.arraysize])

クエリ結果の次の行セットを取得し、タプルのリストを返します。使用可能な行がなくなると、空のリストが返されます。

呼び出しごとに取得する行数は、パラメーターによって指定されます。指定されていない場合、カーソルの 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 が発生します。

size パラメータに関連するパフォーマンス上の考慮事項があることに注意してください。最適なパフォーマンスを得るには、通常、arraysize 属性を使用するのが最適です。size パラメーターを使用する場合、fetchmany() 呼び出しから次の呼び出しまで同じ値を保持するのが最善です。

リスト項目

フェッチオール()

クエリ結果のすべての (残りの) 行を取得し、それらをタプルのリストとして返します。取得するレコードがこれ以上ない場合は、空のリストが返されます。

>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchall()
[(1, 100, "abc'def"), (2, None, 'dada'), (3, 42, 'bar')]

execute*() への前の呼び出しが結果セットを生成しなかった場合、または呼び出しがまだ発行されていない場合は、ProgrammingError が発生します。

于 2018-10-09T07:05:02.703 に答える
11

これらは実装固有です。

  • フェッチオール

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

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

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

  • フェッチマン

fetchmany は、必要な数の結果のみを取得します。結果を出して処理することができます。fetchmany の実装の簡単なスニペット。

   while True:
    results = cursor.fetchmany(arraysize)
    if not results:
        break
    for result in results:
        yield result
于 2016-08-19T12:53:11.887 に答える