1

以下は私のコードによくあるパターンで、カーソルと接続の内部についてもっと知りたいと思っていました。

cursor = connection.cursor()
cursor.execute("SET NAMES utf8")
cursor.execute(sql, args)
results = cursor.fetchall()
cursor.close()

データベースへの接続とカーソルの違いは何ですか? 接続を開いていることのマイナス面はありますか (たとえば、数分間?)。クローズされていないカーソルがあるとどうなりますか?その効果は何ですか? 複数のSQL文を連続して実行する場合、毎回新しいカーソルを作成する必要がありますか?

4

2 に答える 2

3

それは、基になる実装 (Cursor オブジェクトが実際にドライバー内にあるもの) に依存します。

多くの DB-api 実装では、特に結果セットを返すクエリを実行していない場合、Cursor オブジェクトは「興味深い」ものではありません (つまり、多数のオブジェクトを保持して GC に心配させることができます)。

私は Oracle で Python を使用したことはありませんが、(JDBC などの経験に基づいて) Oracle ではそうではないのではないかと思います。Oracle JDBC ドライバーにはサーバー側のカーソルがあり、これをすばやく閉じることが非常に重要です (接続ごとのデフォルトのカーソル制限はかなり低く、制限を超えると、別のカーソルを開こうとすると失敗します)。

Oracle では、カーソルを閉じるために GC に依存することは危険です。たとえば、ループ内で新しいカーソルを開き、ループ関数が戻るまで GC がすべてのカーソルを保持する場合です。

これが当てはまる場合は、 with ステートメントの構造を使用して、例外が発生した場合でもカーソルがタイムリーに閉じられるようにすることが役立つ場合があります。


更新: contextlib.closing を次のようなコンテキストマネージャとして使用できます

with contextlib.closing(myconnection.cursor()) as curs:
  curs.execute(...
  # even if exception happens, cursor is still closed immediately 
  # after this block
于 2012-06-05T21:05:14.257 に答える
1

カーソルは、Python のイテレータに似たものです。結果セット全体をメモリに保持せずにトラバースできます。カーソルは、使用している RDBMS ごとに異なる方法で実装できます。

ガベージ コレクターがカーソルを削除しない場合、閉じられていないカーソルはメモリを使用します。

1 つの接続内で複数のカーソルを開くことができます。

接続を開いたままにすることができます。使用しているデータベースによっては、開いている接続がいくつかのリソースを使用し、一度に開くことができる接続の数に制限がある場合があります。

于 2012-06-05T21:03:56.103 に答える