Daten in Datenbank speichern: INSERT INTO
Auch zum Eintragen von Daten in die Datenbank gibt es die entsprechende SQL-Anweisung. Diese lautet INSERT INTO
. Als Nächstes muss die entsprechende Tabelle angegeben werden:
INSERT INTO tabellennamen
In unserem Beispiel in die Tabelle mit dem Namen „personen“:
INSERT INTO personen
Jetzt werden im nächsten Schritt die Daten (engl. „values“) übergeben – die Daten werden in Klammern geschrieben:
INSERT INTO personen VALUES ()
Die Daten werden in der Reihenfolge eingegeben, wie wir die Felder festgelegt haben. Also in unserem Beispiel: vorname, nachname, geburtstag
Wir wollen unseren „Johann Wolfgang von Goethe“ mit aufnehmen. Geboren wurde er am 28.8.1749.
Unsere SQL-Anweisung ergänzen wir entsprechend:
INSERT INTO personen VALUES (Johann Wolfgang von Goethe 28.8.1749)
So weit, so gut. In diesem Fall, nicht gut. Warum? Die Datenbank weiß nicht, was zusammengehört: wo hört der Vorname auf und wo fängt der Nachname an. Daher werden Daten, die zu einem Feld gehören, jeweils in Anführungszeichen gesetzt. Dabei nutzt man sehr gerne einfache Anführungszeichen, da unsere SQL-Anweisung selber oft als String erstellt wird.
Probieren wir es aus:
INSERT INTO personen VALUES ('Johann Wolfgang von', 'Goethe', '28.8.1749')
Ob das nun passt oder nicht, sagt uns einfach die Reaktion der Datenbank. Also testen!
Unser kompletter Python-Code bisher:
import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()
sql_anweisung = """
CREATE TABLE IF NOT EXISTS personen (
vorname VARCHAR(20),
nachname VARCHAR(30),
geburtstag DATE
);"""
zeiger.execute(sql_anweisung)
sql_anweisung = """
INSERT INTO personen VALUES ('Johann Wolfgang von', 'Goethe', '28.8.1749')
"""
zeiger.execute(sql_anweisung)
verbindung.commit()
verbindung.close()
Beim Ausführen bekommen wir keine Fehlermeldung. Scheint also geklappt zu haben. Spannend wird es, wenn wir die Daten wieder auslesen. Wenn die Daten exakt so wieder herauskommen, dann passt es. Oder doch nicht?
Wer auf die Auflösung der Anmerkung nicht warten kann, hier der Typ dazu. In SQLite unterstützt die folgenden Datentypen: INTEGER, REAL, TEXT, BLOB und NULL. Wenn mir mit DATE ums Eck kommen, kommt zwar keine Fehlermeldung aber effektiv wird es als TEXT gespeichert! Gespeichert ist es, nur mit Datum „rechnen“ können wir erst nach irgendwelchen Umwandlungsaktion über Python.
Variablen nutzen für die INSERT
-SQL-Anweisung
Gerade haben wir eine SQL-Anweisung über INSERT INTO
aufgebaut und direkt in der SQL-Anweisung die Daten mitgegeben. Das wird in den seltensten Fällen zielführend sein. Meistens liegen uns Werte in Variablen vor, die z.B. über Nutzereingaben erfasst worden sind.
Bauen wir also unsere SQL-Anweisung über Variablen auf. Wir bleiben beim gleichen Beispiel oben und ergänzen weitere bekannte Namen in unserer Datenbank, die man schon immer mal gerne in seiner Adressliste gehabt hätte.
nachname = "Schiller"
vorname = "Friedrich"
geburtstag = "10.11.1759"
Und jetzt bauen wir eine SQL-Anweisung (die noch nicht optimal ist!):
zeiger.execute("INSERT INTO personen VALUES (vorname, nachname, geburtstag)")
Warum ist diese Vorgehensweise so nicht gut? Über solche Konstruktionen wird die Datenbank anfällig für SQL-Injektions. Sprich von außen wird schadhafter Code eingebracht, der dann unter Umständen direkt ausgeführt wird. Schlimmstenfalls könnte die komplette Datenbank gelöscht oder Daten ausgespäht werden.
Daher wollen wir die Daten nicht ungeprüft übergeben. Der folgende Aufbau filtert die größten Probleme heraus:
zeiger.execute("INSERT INTO personen VALUES (?,?,?)", (vorname, nachname, geburtstag))
Man sieht an der oberen Zeile, dass die SQL-Anweisung sehr lang werden kann und man nach rechts scrollen muss. Das ist natürlich einerseits unpraktisch und andererseits verbessert es nicht die Lesbarkeit. Abhilfe schafft die Technik der 3 Anführungszeichen einsetzen. Somit hat Python kein Problem mehr, wenn wir unsere Anweisung in mehrere Zeilen verteilen. Das macht besonders bei SQL-Anweisungen Sinn, da wir dann die Felder von den Variablen besser getrennt darstellen können.
Hier die Anweisung von oben sinnvoll in mehrere Zeilen umgebrochen:
zeiger.execute("""
INSERT INTO personen
VALUES (?,?,?)
""",
(vorname, nachname, geburtstag)
)
Und nun der komplette Code:
import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()
nachname = "Schiller"
vorname = "Friedrich"
geburtstag = "10.11.1759"
zeiger.execute("""
INSERT INTO personen
VALUES (?,?,?)
""",
(vorname, nachname, geburtstag)
)
verbindung.commit()
verbindung.close()
Im folgenden Kapitel speichern wir mehrere Datensätze auf einen Rutsch – nicht nur einen wie bisher.