Fachkonzept - Cursor

Wenn die Verbindung zu einer Datenbank steht, fehlen nur die Mittel, um auch Daten aus der Datenbank zu lesen:

Cursor sind Objekte, die es erlauben, die Datensätze aus einer Datenbank-Anfrage auszulesen. Sie zeigen (daher der Name) in der Regel auf einen der Datensätze, dessen Daten dann gelesen werden können.

Das Beispiel in Python:

cursor = con.cursor()
SQLBefehl = "SELECT Name, Einwohner FROM kontinent"
cursor.execute(SQLBefehl)

row=cursor.fetchone()
while (row!=None):
  print(row[0], row[1])
  row = cursor.fetchone()

cursor.close()

Der Befehl con.cursor() erzeugt ein neues leeres Cursor-Objekt aus der zuvor hergestellten Datenbank-Verbindung (con). Dann folgt die Erzeugung und Verarbeitung der Datensätze:

KlickenKlicke auf die einzelnen Schritte zur Veranschaulichung.

Veranschaulichung der Verarbeitung eines SQL-Cursors in Python
  1. Die Methode cursor.execute(SQLBefehl) sendet den SQL-Befehl an die Datenbank, die diesen ausführt. Dabei werden in der Regel noch keine Daten auf den Client übertragen.
  2. Mit dem Aufruf der Methode (Funktion) row = cursor.fetchone() wird der erste Datensatz gelesen und in der Liste row gespeichert. Auf die Elemente der Liste kann dann zugegriffen werden.
  3. Weitere Aufrufe der Methode row = cursor.fetchone() liefern dann die folgenden Datensätze.
  4. Ist der letzte Datensatz erreicht, wird von der Methode None zurückgegeben.

Ergebnisse als Dictionary

Manchmal wäre es praktischer, die einzelnen Spalten der Datensätze nicht über Nummern wie in einer Liste anzusprechen. Dafür gibt es eine spezielle Subklasse der Cursor, die mit dem Zusatz dictionary=True erzeugt werden.

Dann kann über die Spaltennamen zugegriffen werden:

cursor = con.cursor(dictionary=True)
SQLBefehl = "SELECT Name, Einwohner FROM kontinent"
cursor.execute(SQLBefehl)

row=cursor.fetchone()
while (row!=None):
  print(row['Name'], row['Einwohner'])
  row = cursor.fetchone()

cursor.close()

Einschränkungen des Cursors

Das folgende Programm führt in der Zeile cursor.close() zu einer Fehlermeldung:

cursor = con.cursor(dictionary=True)
SQLBefehl = "SELECT Name, Einwohner FROM kontinent ORDER BY Einwohner DESC"
cursor.execute(SQLBefehl)

row=cursor.fetchone()
# Ich will nur den größten Kontinent:
print(row['Name'], row['Einwohner'])

cursor.close()
Fehlermeldung, falls nicht alle Datensätze geholt wurden

Der Grund liegt darin, dass der installierte MySQL-Connector nur dann einen Cursor schließen (oder neu benutzen) kann, wenn alle Datensätze gelesen wurden.

Die folgende Ergänzung kann hier helfen:

cursor = con.cursor(dictionary=True)
SQLBefehl = "SELECT Name, Einwohner FROM kontinent ORDER BY Einwohner DESC"
cursor.execute(SQLBefehl)

row=cursor.fetchone()
# Ich will nur den größten Kontinent:
print(row['Name'], row['Einwohner'])

restRows = cursor.fetchall()
cursor.close()

In restRows sind alle restlichen Datensätze gespeichert und können auch ausgelesen werden. Das ist grundsätzlich auch eine Möglichkeit, alle Datensätze auf einmal zu lesen:

cursor = con.cursor(dictionary=True)
SQLBefehl = "SELECT Name, Einwohner FROM kontinent ORDER BY Einwohner DESC"
cursor.execute(SQLBefehl)

rows = cursor.fetchall()
for r in rows:
  print(r['Name'], r['Einwohner'])

cursor.close()
X

Fehler melden

X

Suche