Python: Datenbanken
Willemers Informatik-Ecke
Wenn Daten längerfristig benötigt werden, müssen Sie in Dateien geschrieben werden. Sobald es sich um strukturierte Daten handelt, sollte man eine Datenbank in Erwägung ziehen. Es ist vermutlich einfacher eine Datenbank zu verwenden, als eine eigenständige Lösung zu basteln. In Sachen Performance ist die Datenbank einer eigenen Lösung immer überlegen. Und kosten muss sie auch nichts.

Python kann mit verschiedene Datenbanken umgehen: Von PostgreSQL über MySQL bis hin zu Oracle. Selbst eine kleine Datenbank namens SQLite steht zur Verfügung. Letztere ist schnell ohne Administrationsarbeit angelegt und leichter programmiert als eine Datei.

Weitere Informationen zu Datenbanken:

Verbindungsaufbau

Für die Verbindungsaufnahme benötigt Python ein passendes Datenbankmodul, das für alle gängigen Datenbanken verfügbar ist.
Modul Datenbank
pg PostgreSQL
MySQLdb MySQL
sqlite3 SQLite
Das passende Modul wird importiert und dessen Methode connect() aufgerufen. Diese liefert ein Connection-Objekt zurück, das für die weiteren Datenbankzugriffe verwendet wird, die dann für alle Datenbanken gleich ist.

Ein kleines Beispiel öffnet eine Verbindung zur Datenbank, fügt einen neuen Satz in die Tabelle kunde und schließt die Verbindung wieder.

#!/usr/bin/python
import pg

conn = pg.connect(db="dbname",user="dbuser", passwd="geheim")
cursor = conn.cursor()
cursor.execute("insert into kunde " + \
  " (kdnr, name, adresse) values " + \
  "(4711, 'Max Kunde', 'Holzweg 7, 22222 Buxtehude')")
conn.commit()
conn.close()
Bei der Verwendung einer MySQL-Datenbank würde sich im Listung nur der Modulname ändern.
import MySQLdb

conn = MySQLdb.connect(db="dbname",
                       user="dbuser",
                       passwd="geheim")
Die Variable conn stellt die Verbindung zur Datenbank her. Über diese werden alle Datenbankaktionen aufgerufen.

Für das Aufrufen der Aktionen für die Datenbank wird ein Cursor verwendet. Er wird durch die Funktion cursor() aus der Verbindung gebildet. Wie im Beispiel zu sehen, werden mit dessen Funktion execute() SQL-Befehle an die Datenbank gesandt. Der Zusammenbau der Befehle sind aus Sicht von Python einfache Zeichenkettenmanipulationen.

Das Ausführen der SQL-Befehle mit execute() funktioniert so lange problemlos, wie das Programm keine Antwort auf seine Befehle erwartet. Das gilt beispielsweise für die SQL-Befehle CREATE, INSERT, UPDATE oder DELETE.

Tabellen erstellen: CREATE

Bevor Sie in der Datenbank Daten ablegen können, müssen Tabellen angelegt werden. Im Produktionsumfeld ist dies eine Aufgabe des Datenbankadministrators. Also Programmierer erhalten Sie nur die Informationen, welche Tabellen zur Verfügung stehen.

Wenn Ihre Anwendung aber selbst seine Datenbankstruktur erstellt, dann müssen Sie die CREATE-Befehle erzeugen. Dazu verwenden Sie die Funktion execute() und übergeben den SQL-Befehl als Parameter. Das folgende Beispiel erzeugt nacheinander je eine Tabelle für Artikel, Lieferanten, Kunden und Kauf.

cursor.execute("""CREATE TABLE artikel ( 
    artnr INTEGER, bez TEXT, lieferant INTEGER)""")
cursor.execute("""CREATE TABLE lieferant ( 
    liefnr INTEGER, name TEXT, telefonnummer TEXT)""")
cursor.execute("""CREATE TABLE kunde ( 
    kdnr INTEGER, name TEXT, anschrift TEXT)""")
cursor.execute("""CREATE TABLE kauf ( 
    rgnr INTEGER, pos INTEGER,
    kdnr INTEGER, artnr INTEGER, bem TEXT)""")
Der SQL-Befehl beginnt mit CREATE TABLE. Es folgt der Name der Tabelle. In der folgenden runden Klammer werden nun die Spalten der Tabelle definiert. Jede Spaltendefinition beginnt mit dem Namen. Dann folgt der SQL-Typ.
Typ Bedeutung
INTEGER Ganzzahliger Wert
TEXT Zeichenkette
VARCHAR Zeichenkette
CHAR(23) Zeichenkette mit 23 Buchstaben
Die Spaltendefinitionen werden durch Kommata voneinander getrennt.

Spalten können spezifiziert werden. Dabei steht UNIQUE dafür, dass ein hier eingetragener Wert nur einmal in der Tabelle vorkommen darf. NOT NULL bedeutet, dass der Wert immer gefüllt werden muss.

Auch die ganze Tabelle kann weitere Spezifikationen haben. Mit PRIMARY KEY werden die Spalte bezeichnet, die einen eindeutigen Schlüssel auf die Tabelle bilden. INDEX bewirkt einen Index für die aufgezählten Spalten, die ein Suchen nach diesen Begriffen erheblich beschleunigt.

Variationen für INSERT

Der Befehl INSERT fügt eine Zeile in eine Tabelle ein. Auf den SQL-Befehl INSERT folgen die Informationen, welche Tabelle gemeint ist und wie die Daten der Spalten aussehen. Zunächst wird mit INTO eingeleitet, wie die Tabelle heißt. Dann folgt auf VALUES eine Klammer, in der die Werte der Zeile eingetragen werden. Wird nichts weiter angegeben, gilt die Reihenfolge, in der die Spalten einmal durch CREATE TABLE angelegt wurden.

Auch dieser Befehl kann über die Funktion execute() an die SQL-Datenbank gesendet werden. Das Beispiel legt Lagerkartoffeln als neuen Artikel an.

cursor.execute("""INSERT INTO artikel VALUES ( 
        47110815, 'Lagerkartoffeln ungeniessbar', 121212)
""")
In der Praxis wird es aber eher so sein, dass die einzufügenden Werte aus Variablen stammen. Mit ein paar gelungenen Pluszeichen lässt sich eine passende Zeichenkette realisieren. Das sieht im Listing aber nicht schön aus. Besser ist der Ansatz, den Wert über ein Dictionary zu füllen.
werte = {"liefernr" : "121212", "name" : "Hinterhof",
         "telefon" : "123456"} 
sql = "INSERT INTO lieferanten VALUES (:liefernr, \
         :name, :telefon)"
cursor.execute(sql, werte)
Das Dictionary werte kann beispielsweise auch aus Eingabefeldern eines Dialogs gefüllt werden.

Statt über den Schlüssel eines Dictionarys kann auch einfach eine Liste verwendet werden. Im String wird dann für jede Position ein Fragezeichen angegeben.

cursor.execute("INSERT INTO artikel VALUES (?,?,?)", artikelVar)

Ergebnisermittlung bei SELECT

Der SQL-Befehl SELECT holt Daten aus der Datenbank. Der Befehl ist sehr flexibel und sehr mächtig. So kann er über mehrere Tabellen hinweg nach Spalten suchen oder Spalten anzeigen. Das Ergebnis eines SELECT-Befehls umfasst typischerweise mehrere Zeilen. Dieses Ergebnis muss natürlich in Python-Variablen überführt werden. Dazu wird nach dem Aufruf von execute() die Funktion fetchall() aufgerufen, die eine Liste liefert.
#!/usr/bin/python
import pg

conn = pg.connect(db="dbname",user="dbuser", passwd="geheim")
cursor = conn.cursor()
cursor.execute("select from kunde")
ergebnis = cursor.fetchall()
if ergebnis:
    for kdnr, name, anschrift in ergebnis:
        print("%6i %30s   %40s" % (kdnr, name, anschrift))
conn.close()

Pythons eigene Datenbank sqlite

Die Fähigkeit des Umgangs mit den großen Datenbanken ist für größere Projekte natürlich unabdingbar. Vielfach ist die Effizienz und die Leistungsfähigkeit einer großen Datenbank gar nicht erforderlich.

Wenn es nur darum geht, Daten strukturiert abzulegen, ist SQLite ein guter Kompromiss. SQLite legt seine Daten in einer lokalen Datei im Arbeitsverzeichnis des Programms ab. Es muss nicht erst eine Datenbank gestartet werden oder eine Netzwerkverbindung eingerichtet werden.

Wie üblich, unterscheidet sich lediglich der Import und die Verbindungsaufnahme von anderen Datenbanken. Der Rest des Programms wie gewohnt.

import sqlite3 
connection = sqlite3.connect("lokaledb.db")
Ist die Datei lokaledb.db nicht vorhanden, wird sie angelegt. Der Dateiname ist völlig frei, auch die Endung. Wird als Parameter statt eines Dateinamens :memory: übergeben, läuft die ganze Datenbank im Hauptspeicher ab. Das hat natürlich zur Konsequenz, dass die Daten nur zur Laufzeit des Programms vorhanden sind.