it-swarm.com.de

Warum müssen Sie einen Cursor erstellen, wenn Sie eine SQLite-Datenbank abfragen?

Ich bin völlig neu in Pythons sqlite3-Modul (und SQL im Allgemeinen für diese Angelegenheit), und das stummelt mich völlig. Unzureichend erscheint auch der Mangel an Beschreibungen von cursor-Objekten (eher ihre Notwendigkeit). 

Dieses Codefragment ist die bevorzugte Art, Dinge zu tun:

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()

Dies ist nicht der Fall, obwohl es genauso gut funktioniert und ohne (scheinbar sinnlose) cursor:

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

Kann mir jemand sagen, warum ich eine cursor brauche?
Es scheint einfach sinnlos zu sein. Für jede Methode in meinem Skript, die auf eine Datenbank zugreift, soll ich eine cursor? .__ erstellen und löschen.
Warum verwenden Sie nicht einfach das connection-Objekt?

96
Jack Bauer

Nur eine falsch angewandte Abstraktion scheint mir. Ein DB-Cursor ist eine Abstraktion, die für das Durchqueren von Datensätzen gedacht ist.

Aus Wikipedia-Artikel zum Thema :

In der Informatik und Technologie ist ein Datenbankcursor ein Steuerelement Struktur, die das Durchlaufen der Datensätze in einer Datenbank ermöglicht . Cursor erleichtern die Weiterverarbeitung in Verbindung mit dem Durchqueren, wie Abrufen, Hinzufügen und Entfernen der Datenbank Aufzeichnungen. Das Datenbankcursormerkmal des Durchlaufs erzeugt Cursor ähnlich dem Programmiersprachenkonzept des Iterators.

Und:

Cursor können nicht nur zum Abrufen von Daten aus dem DBMS in ein .__ verwendet werden. Anwendung, sondern auch zum Identifizieren einer Zeile in einer zu aktualisierenden Tabelle oder gelöscht Der SQL: 2003-Standard definiert positionierte Updates und positionierte Lösch-SQL-Anweisungen für diesen Zweck. Solche Aussagen machen. Verwenden Sie keine reguläre WHERE-Klausel mit Prädikaten. Stattdessen einen Cursor kennzeichnet die Zeile. Der Cursor muss geöffnet und bereits positioniert sein in einer Zeile mittels FETCH-Anweisung.

Wenn Sie docs auf Python sqlite module überprüfen, können Sie feststellen, dass ein Python-Modul cursor selbst für eine CREATE TABLE-Anweisung erforderlich ist. Es wird also für Fälle verwendet, in denen ein reines connection-Objekt ausreicht - wie vom OP richtig angegeben . Diese Abstraktion unterscheidet sich von dem, was die Leute unter einem DB-Cursor verstehen, und daher die Verwirrung/Frustration der Benutzer. Unabhängig von der Effizienz ist dies nur ein konzeptioneller Aufwand. Wäre nett, wenn in den Dokumenten darauf hingewiesen wurde, dass das Python-Modul cursor etwas anders ist als der Cursor in SQL und Datenbanken.

49
Basel Shishani

Sie benötigen ein Cursorobjekt, um Ergebnisse abzurufen. Ihr Beispiel funktioniert, weil es sich um eine INSERT handelt und Sie daher nicht versuchen, Zeilen zurückzugewinnen. Wenn Sie jedoch die sqlite3 docs betrachten, werden Sie feststellen, dass es keine .fetchXXXX-Methoden für Verbindungsobjekte gibt Wenn Sie also versucht haben, eine SELECT ohne Cursor auszuführen, haben Sie keine Möglichkeit, die resultierenden Daten abzurufen.

Mit Cursorobjekten können Sie verfolgen, welche Ergebnismenge welche ist, da es möglich ist, mehrere Abfragen auszuführen, bevor Sie die Ergebnisse der ersten abrufen.

31
Amber

Laut dem offiziellen docsconnection.execute() handelt es sich um eine nichtstandardisierte Abkürzung, die ein Zwischencursorobjekt erstellt:

Verbindung.ausführen
Dies ist eine nicht standardmäßige Verknüpfung, die durch Aufrufen der Cursor () - Methode ein Cursorobjekt erstellt, die Execute () - Methode des Cursors mit den angegebenen Parametern aufruft und den Cursor zurückgibt.

27
user

12.6.8. Sqlite3 effizient verwenden

12.6.8.1. Shortcut -Methoden verwenden

Mit den Methoden nonstandardexecute(), executemany() und executescript() des Connection-Objekts kann Ihr Code prägnanter geschrieben werden, da Sie die (häufig überflüssigen) Cursorobjekte nicht explizit erstellen müssen . Stattdessen werden die Cursor-Objekte implizit erstellt und diese Verknüpfungsmethoden geben die Cursor-Objekte zurück. Auf diese Weise können Sie eine SELECT-Anweisung ausführen und direkt mit einem einzigen Aufruf des Connection-Objekts iterieren.

( sqlite3 Dokumentation ; Hervorhebung meines.)

Warum nicht einfach das Verbindungsobjekt verwenden?

Da diese Methoden des Verbindungsobjekts nicht standard sind, d. H., Sie sind nicht Teil der Python Database API-Spezifikation v2.0 (PEP 249).

Solange Sie die Standardmethoden des Cursor-Objekts verwenden, können Sie sicher sein, dass Ihr Code vollständig portierbar ist, wenn Sie zu einer anderen Datenbankimplementierung wechseln, die der obigen Spezifikation entspricht. Möglicherweise müssen Sie nur die Zeile import ändern.

Wenn Sie jedoch den connection.execute verwenden, besteht die Möglichkeit, dass das Umschalten nicht so einfach ist. Das ist der Hauptgrund, warum Sie stattdessen cursor.execute verwenden möchten.

Wenn Sie jedoch sicher sind, dass Sie nicht wechseln werden, würde ich sagen, dass es völlig in Ordnung ist, die connection.execute-Verknüpfung zu verwenden und "effizient" zu sein.

11
AXO

Es gibt uns die Möglichkeit, mehrere separate Arbeitsumgebungen über dieselbe Verbindung zur Datenbank zu haben.

0
Python Learner