169

私は、Python の sqlite3 モジュール(および一般的な SQL) にまったく慣れていないため、完全に困惑しています。cursorオブジェクトの説明(むしろ必要性) が非常に少ないことも奇妙に思えます。

このコード スニペットは、推奨される方法です。

import sqlite3
conn = sqlite3.connect("db.sqlite")
c = conn.cursor()
c.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
c.close()

これはそうではありませんが、(一見無意味な) なしでも同様に機能しますcursor

import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()

が必要な理由を誰か教えてもらえますcursorか?
無意味なオーバーヘッドのように思えます。データベースにアクセスするスクリプト内のすべてのメソッドについて、cursor? を作成して破棄することになっています。オブジェクト
を使用しないのはなぜですか?connection

4

5 に答える 5

77

抽象化が誤って適用されているように思えます。db カーソルは抽象化であり、データ セットのトラバーサルを目的としています。

件名に関するウィキペディアの記事から:

コンピューター サイエンスとテクノロジーでは、データベース カーソルは、データベース内のレコードのトラバーサルを可能にする制御構造です。カーソルは、データベース レコードの取得、追加、および削除など、トラバーサルと組み合わせた後続の処理を容易にします。トラバーサルのデータベース カーソル特性により、カーソルはプログラミング言語の反復子の概念に似たものになります。

と:

カーソルは、DBMS からアプリケーションにデータをフェッチするだけでなく、更新または削除するテーブル内の行を識別するためにも使用できます。SQL:2003 標準では、その目的のために位置指定更新および位置指定削除の SQL ステートメントが定義されています。このようなステートメントは、述語を含む通常の WHERE 句を使用しません。代わりに、カーソルが行を識別します。FETCH ステートメントを使用して、カーソルが開かれ、すでに行に配置されている必要があります。

Python sqlite moduleのドキュメントを確認するcursorと、ステートメントでも python モジュールが必要であることがわかります。そのため、OP で正しく指摘されているようCREATE TABLEに、単なるオブジェクトで十分な場合に使用されます。connectionこのような抽象化は、人々が db カーソルを理解しているものとは異なるため、ユーザー側の混乱/フラストレーションとは異なります。効率に関係なく、それは単なる概念上のオーバーヘッドです。cursorPythonモジュールがSQLやデータベースのカーソルとは少し異なることがドキュメントで指摘されていればいいでしょう。

于 2012-11-30T04:52:28.517 に答える
52

公式ドキュメント によると、中間カーソル オブジェクトを作成するconnection.execute()標準のショートカットがあります。

Connection.execute
これは、cursor() メソッドを呼び出してカーソル オブジェクトを作成し、指定されたパラメーターでカーソルの execute() メソッドを呼び出し、カーソルを返す非標準のショートカットです。

于 2011-07-02T10:47:13.233 に答える
46

結果を取得するにはカーソル オブジェクトが必要です。あなたの例はそれがであるためINSERT、それから行を取得しようとしていないため機能しますが、sqlite3docs.fetchXXXXを見ると、接続オブジェクトにメソッドがないことに気付くでしょう。カーソルがSELECTないと、結果のデータを取得する方法がありません。

カーソル オブジェクトを使用すると、最初の結果の取得が完了する前に複数のクエリを実行できるため、どの結果セットがどれであるかを追跡できます。

于 2011-06-11T19:46:35.323 に答える
38

12.6.8. sqlite3 を効率的に使用する

12.6.8.1. ショートカットメソッドの使用

非標準 execute()executemany()およびexecutescript()Connection オブジェクトのメソッドを使用すると、(多くの場合余分な) Cursor オブジェクトを明示的に作成する必要がないため、コードをより簡潔に記述できます。代わりに、Cursor オブジェクトが暗黙的に作成され、これらのショートカット メソッドはカーソル オブジェクトを返します。このようにして、SELECT ステートメントを実行し、Connection オブジェクトを 1 回呼び出すだけで、それを直接反復処理できます。

( sqlite3 ドキュメント; 重点鉱山。)

接続オブジェクトを使用しないのはなぜですか?

接続オブジェクトのこれらのメソッドは非標準であるため、つまり、Python データベース API 仕様 v2.0 (PEP 249) の一部ではありません。

Cursor オブジェクトの標準メソッドを使用している限り、上記の仕様に従う別のデータベース実装に切り替えた場合、コードは完全に移植可能になります。おそらく、行を変更するだけで済みますimport

ただし、 を使用するconnection.executeと、切り替えがそれほど簡単ではない可能性があります。cursor.executeこれが、代わりに使用する主な理由です。

connection.executeただし、切り替えないことが確実な場合は、ショートカットを使用して「効率的」にすることはまったく問題ないと思います。

于 2015-05-26T16:47:59.633 に答える