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:
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.
Bei der Verwendung von SQLite ist dies nicht (direkt) möglich.
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()
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()