Python MySQL DELETE – Zeilen aus einer Tabelle entfernen
Zeilen aus einer MySQL-Datenbank in Python löschen mit mysql-connector-python, parametrisierten Abfragen, Massen-Deletes und Fehlerbehandlung.
Das Entfernen von Datensätzen aus einer MySQL-Datenbank ist eine Routineaufgabe in jeder datengetriebenen Python-Anwendung — sei es das Löschen abgelaufener Sitzungen, das Entfernen eines Benutzerkontos oder das Archivieren alter Bestellungen. Dieses Kapitel zeigt, wie Sie die SQL-Anweisung DELETE über die Bibliothek mysql-connector-python verwenden, und behandelt das Löschen einzelner Zeilen, Massen-Deletes, sichere parametrisierte Abfragen, Transaktionen und Fehlerbehandlung.
Voraussetzungen
Vor dem Ausführen der Beispiele benötigen Sie Folgendes:
- Python 3.8 oder höher installiert
mysql-connector-pythoninstalliert (pip install mysql-connector-python)- Einen laufenden MySQL-Server (lokal oder remote)
- Eine Datenbank und eine Tabelle zum Arbeiten (siehe MySQL Get Started und MySQL Create Table)
Die folgenden Beispiele setzen voraus, dass Sie bereits eine Datenbank namens mydatabase besitzen, die eine customers-Tabelle enthält, die im Kapitel MySQL Insert erstellt und befüllt wurde.
Die DELETE-Anweisung
Die SQL-Anweisung DELETE entfernt eine oder mehrere Zeilen aus einer Tabelle:
DELETE FROM table_name WHERE condition;Verwenden Sie immer eine WHERE-Klausel. Ohne sie werden alle Zeilen in der Tabelle gelöscht. MySQL warnt Sie nicht — die gesamte Tabelle wird sofort geleert.
Verbindung zu MySQL herstellen
Bevor Sie eine Anweisung ausführen, müssen Sie eine Verbindung öffnen und ein Cursor-Objekt erstellen. Der Cursor ist das Objekt, das SQL an den Server sendet und Ergebnisse abruft.
import mysql.connector
from mysql.connector import Error
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()Eine einzelne Zeile löschen
Die sicherste Methode, genau eine Zeile anzusprechen, ist eine parametrisierte Abfrage. Übergeben Sie den Wert als Python-Tuple — der Connector ersetzt den Platzhalter %s nach dem Escapen des Werts, was SQL-Injection verhindert.
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 = "DELETE FROM customers WHERE name = %s"
val = ("John",) # note the trailing comma — this is a tuple
mycursor.execute(sql, val)
mydb.commit() # write the change to disk
print(mycursor.rowcount, "record(s) deleted")
except Error as e:
print(f"Error: {e}")
mydb.rollback() # undo any partial changes on failure
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()cursor.rowcount gibt an, wie viele Zeilen die Anweisung tatsächlich entfernt hat. Der Wert 0 bedeutet, dass die WHERE-Bedingung nichts gefunden hat — die Abfrage wurde fehlerfrei ausgeführt, aber es wurde nichts gelöscht.
Warum commit() erforderlich ist
mysql-connector-python öffnet Verbindungen standardmäßig im Modus autocommit off. Solange Sie mydb.commit() nicht aufrufen, existiert die Löschung nur innerhalb Ihrer aktuellen Transaktion und ist für andere Verbindungen unsichtbar. Wenn Ihr Skript vor dem Commit abstürzt, wird die Löschung automatisch zurückgerollt. Rufen Sie mydb.rollback() explizit im except-Block auf, um die Absicht klarzumachen.
Mehrere Zeilen mit einer einzigen Anweisung löschen
Wenn Sie alle Zeilen löschen möchten, die einem Muster entsprechen, behalten Sie die WHERE-Klausel bei, aber erweitern Sie die Bedingung. Es wird nur ein einziger execute()-Aufruf benötigt.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Delete every customer whose address contains "Highway"
sql = "DELETE FROM customers WHERE address LIKE %s"
val = ("%Highway%",)
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "record(s) deleted")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Zeilen anhand mehrerer IDs löschen (executemany)
Wenn Sie eine Liste von Primärschlüsseln zum Entfernen haben, verwenden Sie executemany(), um dieselbe parametrisierte Anweisung pro Element in einem einzigen Roundtrip auszuführen:
import mysql.connector
from mysql.connector import Error
ids_to_delete = [(5,), (12,), (17,), (34,)] # list of 1-tuples
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "DELETE FROM customers WHERE id = %s"
mycursor.executemany(sql, ids_to_delete)
mydb.commit()
print(mycursor.rowcount, "record(s) deleted")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()executemany() fasst alle einzelnen Löschvorgänge in einer einzigen Transaktion zusammen, sodass entweder alle erfolgreich sind oder keiner.
Verwendung eines Context Managers (empfohlenes Muster)
Das Öffnen der Verbindung innerhalb einer with-Anweisung stellt sicher, dass sie immer geschlossen wird, auch wenn während der Ausführung eine Ausnahme auftritt. Dies ist das sauberste Muster für Produktionscode:
import mysql.connector
from mysql.connector import Error
db_config = {
"host": "localhost",
"user": "yourusername",
"password": "yourpassword",
"database": "mydatabase",
}
try:
with mysql.connector.connect(**db_config) as mydb:
with mydb.cursor() as mycursor:
sql = "DELETE FROM customers WHERE name = %s"
mycursor.execute(sql, ("Alice",))
mydb.commit()
print(mycursor.rowcount, "record(s) deleted")
except Error as e:
print(f"Error: {e}")Der with-Block schließt sowohl den Cursor als auch die Verbindung, wenn der Block endet — unabhängig davon, ob eine Ausnahme ausgelöst wurde.
Zeilen vor dem Löschen zählen (Probelauf)
Bevor Sie ein destruktives DELETE ausführen, empfiehlt es sich, zunächst ein SELECT COUNT(*) mit derselben WHERE-Klausel auszuführen. Dies dient als Probelauf und zeigt Ihnen, wie viele Zeilen betroffen wären:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
condition = "%Highway%"
# Dry run: count matching rows first
mycursor.execute("SELECT COUNT(*) FROM customers WHERE address LIKE %s", (condition,))
count = mycursor.fetchone()[0]
print(f"{count} row(s) would be deleted")
if count > 0:
mycursor.execute("DELETE FROM customers WHERE address LIKE %s", (condition,))
mydb.commit()
print(f"{mycursor.rowcount} row(s) deleted")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Häufige Fehler
Die WHERE-Klausel vergessen
# DANGER: deletes every row in the table
mycursor.execute("DELETE FROM customers")
mydb.commit()Überprüfen Sie immer, ob Ihre WHERE-Klausel vorhanden und korrekt ist, bevor Sie commit() aufrufen.
Einen string statt eines Tuples übergeben
# Wrong — passes the string "John" character by character
mycursor.execute("DELETE FROM customers WHERE name = %s", "John")
# Correct — wrap the value in a tuple
mycursor.execute("DELETE FROM customers WHERE name = %s", ("John",))commit() nicht aufrufen
mycursor.execute("DELETE FROM customers WHERE name = %s", ("John",))
# Missing mydb.commit() — the deletion will be silently rolled back
# when the connection closesBest Practices
- Verwenden Sie parametrisierte Abfragen (
%s-Platzhalter) zu jeder Zeit. Bauen Sie niemals SQL-Strings mit f-Strings oder+-Verkettung aus vom Benutzer stammenden Daten — das öffnet eine SQL-Injection-Lücke. - Committen oder rollen Sie immer explizit zurück. Sich darauf zu verlassen, dass das Schließen der Verbindung eine Transaktion zurückrollt, ist verwirrend; machen Sie das Ergebnis in Ihrem Code explizit.
- Prüfen Sie
rowcountnach dem Löschen, um zu bestätigen, dass die erwartete Anzahl von Zeilen entfernt wurde. - Verwenden Sie Transaktionen für mehrstufige Löschvorgänge. Wenn Sie Zeilen aus mehreren verknüpften Tabellen löschen müssen (z. B. eine Bestellung und ihre Positionen), fassen Sie die Operationen in einer einzigen Transaktion zusammen, damit keine verwaisten Daten entstehen.
- Fügen Sie geeignete Indizes hinzu für Spalten, die in
WHERE-Klauseln verwendet werden. Ein Delete, der die gesamte Tabelle durchsucht, ist bei großen Datenmengen langsam.
Verwandte Kapitel
- MySQL Get Started — Connector installieren und erste Verbindung herstellen
- MySQL Create Table — Tabellen erstellen, aus denen Sie löschen werden
- MySQL Insert — Zeilen hinzufügen, bevor Sie das Entfernen üben
- MySQL Update — Zeilen ändern statt sie zu entfernen
- MySQL Where — die
WHERE-Klausel meistern, die in allenDELETE-Anweisungen verwendet wird - MySQL Drop Table — eine gesamte Tabellenstruktur entfernen, nicht nur ihre Zeilen