MySQL Insert in Python
Lernen Sie, einzelne und mehrere Zeilen einzufügen und Auto-Increment-IDs in MySQL mit mysql-connector-python zu verarbeiten.
Um Daten aus Python in eine MySQL-Tabelle einzufügen, benötigen Sie drei Dinge: eine aktive Verbindung, eine parametrisierte SQL-Anweisung und einen Aufruf von commit(). Dieses Kapitel behandelt das Einfügen einzelner Zeilen, das Massen-Einfügen mit executemany(), das Abrufen der automatisch generierten ID der neuen Zeile, den Umgang mit Duplikaten mittels ON DUPLICATE KEY UPDATE sowie häufige Fallstricke für Einsteiger.
Voraussetzungen
Stellen Sie sicher, dass Folgendes vorhanden ist, bevor Sie die Beispiele ausführen:
- Python 3.x und ein laufender MySQL-Server
mysql-connector-pythoninstalliert:
pip install mysql-connector-python- Eine Datenbank und eine
customers-Tabelle, die bereits erstellt wurden — siehe MySQL Create Database und MySQL Create Table, falls Sie diese zuerst einrichten müssen.
Die Beispiele setzen folgende Tabellendefinition voraus:
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255)
);Verbindung zu MySQL herstellen
Jede Operation beginnt mit einem Verbindungsobjekt. Übergeben Sie Ihren Host, Ihre Anmeldedaten und den Datenbanknamen an mysql.connector.connect() und erstellen Sie dann einen Cursor:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()Das cursor-Objekt sendet SQL an den Server. Verwenden Sie dieselbe Verbindung für mehrere Anweisungen, anstatt sich jedes Mal neu zu verbinden.
Eine einzelne Zeile einfügen
Verwenden Sie die SQL-Anweisung INSERT INTO mit %s-Platzhaltern und übergeben Sie die tatsächlichen Werte als Tupel. Erstellen Sie niemals die Abfragezeichenkette mit Pythons %- oder f-String-Formatierung — das öffnet Ihren Code für SQL-Injection.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"
val = ("John", "Highway 21")
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "record inserted.")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Wichtige Punkte:
%sist die Platzhalter-Syntax fürmysql-connector-python, unabhängig vom Datentyp der Spalte (Zeichenketten, Ganzzahlen und Datumsangaben verwenden alle%s).mydb.commit()ist erforderlich — ohne diesen Aufruf wird die eingefügte Zeile niemals auf dem Datenträger gespeichert. MySQL umschließt DML-Anweisungen in implizite Transaktionen; Sie müssen einen Commit durchführen, um sie abzuschließen.mydb.rollback()imexcept-Block macht alle unvollständigen Änderungen rückgängig, wenn die Anweisung fehlschlägt.
Die Auto-Increment-ID abrufen
Nach einem erfolgreichen Einfügen enthält mycursor.lastrowid den AUTO_INCREMENT-Primärschlüssel, den MySQL der neuen Zeile zugewiesen hat:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"
val = ("Alice", "Maple Street 7")
mycursor.execute(sql, val)
mydb.commit()
print("Inserted row ID:", mycursor.lastrowid)
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Beispielausgabe:
Inserted row ID: 1Der Wert ist 0, wenn die Tabelle keine AUTO_INCREMENT-Spalte hat. Verwenden Sie lastrowid, um den neuen Datensatz sofort in verknüpften Tabellen zu referenzieren (zum Beispiel, um eine passende Zeile in eine orders-Tabelle einzufügen).
Mehrere Zeilen einfügen
executemany() sendet eine Liste von Wertetupeln in einem einzigen Datenbankaufruf an den Server, was wesentlich effizienter ist als der Aufruf von execute() in einer Schleife:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"
vals = [
("Peter", "Lowstreet 4"),
("Amy", "Apple St 652"),
("Hannah", "Mountain 21"),
("Michael", "Valley 345"),
("Sandy", "Ocean Blvd 2"),
("Betty", "Green Grass 1"),
("Richard", "Sky St 331"),
("Susan", "One Way 98"),
("Vicky", "Yellow Garden 2"),
("Ben", "Park Lane 38"),
("William", "Central St 954"),
("Chuck", "Main Road 989"),
("Viola", "Sideway 1633"),
]
mycursor.executemany(sql, vals)
mydb.commit()
print(mycursor.rowcount, "records inserted.")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Beispielausgabe:
13 records inserted.mycursor.rowcount gibt nach executemany() die Gesamtzahl der betroffenen Zeilen über alle Tupel hinweg zurück.
Wann executemany() einer Schleife vorzuziehen ist
| Ansatz | Datenbankaufrufe | Verwenden wenn |
|---|---|---|
execute() in einer Schleife | Einer pro Zeile | Zeilen voneinander abhängen |
executemany() | Einer insgesamt | Unabhängige Zeilen in großer Anzahl eingefügt werden |
Bei sehr großen Datensätzen (Zehntausende von Zeilen) sollten Sie in Blöcken von 500–1000 Zeilen arbeiten, damit ein einzelner Fehler nicht die gesamte Operation verwirft.
Einfügen ohne Fehler bei Duplikaten
Wenn Ihre Tabelle eine UNIQUE-Bedingung hat und Sie versuchen, eine bereits vorhandene Zeile einzufügen, löst MySQL einen Fehler wegen doppeltem Schlüssel aus. Zwei gängige Strategien vermeiden dies:
INSERT IGNORE
INSERT IGNORE überspringt stillschweigend Zeilen, die eine Eindeutigkeitsbedingung verletzen:
sql = "INSERT IGNORE INTO customers (name, address) VALUES (%s, %s)"
mycursor.execute(sql, ("John", "Highway 21"))
mydb.commit()
print(mycursor.rowcount, "row(s) affected") # 0 if row already existedON DUPLICATE KEY UPDATE
ON DUPLICATE KEY UPDATE führt eine Aktualisierung durch, wenn der eindeutige Schlüssel bereits vorhanden ist, und macht die Anweisung zu einem "Upsert" (Einfügen oder Aktualisieren):
sql = """
INSERT INTO customers (name, address)
VALUES (%s, %s)
ON DUPLICATE KEY UPDATE address = VALUES(address)
"""
mycursor.execute(sql, ("John", "New Address 5"))
mydb.commit()
# rowcount is 1 for insert, 2 for update, 0 if row existed but was unchanged
print(mycursor.rowcount, "row(s) affected")Verwenden Sie ON DUPLICATE KEY UPDATE, wenn Sie den aktuellsten Wert speichern möchten, unabhängig davon, ob die Zeile neu war oder bereits vorhanden war.
Daten aus einem Dictionary einfügen
Wenn Ihre Daten als Liste von Dictionaries vorliegen (zum Beispiel aus einer geparsten JSON-Nutzlast), können Sie SQL und Werte dynamisch aufbauen:
import mysql.connector
from mysql.connector import Error
customers = [
{"name": "Eva", "address": "Elm Street 3"},
{"name": "Oscar", "address": "Birch Lane 9"},
]
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "INSERT INTO customers (name, address) VALUES (%(name)s, %(address)s)"
mycursor.executemany(sql, customers)
mydb.commit()
print(mycursor.rowcount, "records inserted.")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Benannte Platzhalter (%(name)s) machen die Absicht klarer, wenn Dictionaries verwendet werden, und verringern das Risiko, Positionswerte falsch zuzuordnen.
Häufige Fehler vermeiden
commit() vergessen — Das Einfügen scheint zu funktionieren (kein Fehler), aber es werden keine Daten gespeichert. Rufen Sie mydb.commit() immer nach DML-Anweisungen auf.
SQL mit Zeichenkettenformatierung erstellen — Die Verwendung von f-Strings oder %-Formatierung zum Einbetten von Benutzereingaben ist die häufigste Quelle von SQL-Injection. Übergeben Sie Werte stets als zweites Argument an execute().
Verbindungen offen lassen — Verwenden Sie einen finally-Block (oder einen Kontextmanager), um sicherzustellen, dass cursor.close() und mydb.close() immer aufgerufen werden.
INSERT verwenden, bevor die Tabelle erstellt wurde — Sie erhalten einen Fehler Table 'mydatabase.customers' doesn't exist. Führen Sie zuerst CREATE TABLE aus oder prüfen Sie mit SHOW TABLES. Siehe MySQL Create Table.
Nächste Schritte
Sobald Ihre Zeilen eingefügt sind, möchten Sie diese in der Regel wieder auslesen. Siehe MySQL Select für SELECT-Abfragen, MySQL Where zum Filtern und MySQL Update zum Ändern bestehender Zeilen.