Python MySQL DELETE – Eliminare Righe da una Tabella
Scopri come eliminare righe da un database MySQL in Python con mysql-connector-python, query parametrizzate sicure, eliminazioni in blocco e gestione degli errori.
Rimuovere record da un database MySQL è un'operazione di routine in qualsiasi applicazione Python orientata ai dati — che tu stia eliminando sessioni scadute, rimuovendo un account utente o archiviando vecchi ordini. Questo capitolo mostra come usare l'istruzione SQL DELETE tramite la libreria mysql-connector-python, coprendo eliminazioni di singole righe, eliminazioni in blocco, query parametrizzate sicure, transazioni e gestione degli errori.
Prerequisiti
Prima di eseguire gli esempi sono necessari i seguenti elementi:
- Python 3.8 o versione successiva installato
mysql-connector-pythoninstallato (pip install mysql-connector-python)- Un server MySQL in esecuzione (locale o remoto)
- Un database e una tabella su cui lavorare (vedi MySQL Get Started e MySQL Create Table)
Gli esempi seguenti presuppongono che tu abbia già un database chiamato mydatabase contenente una tabella customers creata e popolata nel capitolo MySQL Insert.
L'istruzione DELETE
L'istruzione SQL DELETE rimuove una o più righe da una tabella:
DELETE FROM table_name WHERE condition;Includi sempre una clausola WHERE. Senza di essa, ogni riga della tabella viene eliminata. MySQL non ti avvisa — l'intera tabella viene azzerata istantaneamente.
Connessione a MySQL
Prima di eseguire qualsiasi istruzione devi aprire una connessione e creare un oggetto cursore. Il cursore è l'oggetto che invia SQL al server e recupera i risultati.
import mysql.connector
from mysql.connector import Error
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()Eliminare una Singola Riga
Il modo più sicuro per individuare una riga specifica è una query parametrizzata. Passa il valore come tupla Python — il connettore sostituisce il segnaposto %s dopo aver eseguito l'escaping del valore, il che previene l'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 = "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 indica quante righe l'istruzione ha effettivamente rimosso. Un valore di 0 significa che la condizione WHERE non ha trovato corrispondenze — la query è stata eseguita senza errori, ma non è stata eliminata alcuna riga.
Perché commit() è obbligatorio
mysql-connector-python apre le connessioni in modalità autocommit off per impostazione predefinita. Fino a quando non chiami mydb.commit(), l'eliminazione esiste solo all'interno della transazione corrente ed è invisibile ad altre connessioni. Se lo script si blocca prima del commit, l'eliminazione viene automaticamente annullata. Chiama mydb.rollback() esplicitamente nel blocco except per rendere chiara l'intenzione.
Eliminare Più Righe con una Singola Istruzione
Se vuoi eliminare tutte le righe che corrispondono a un pattern, mantieni la clausola WHERE ma amplia la condizione. È necessaria una sola chiamata a execute().
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()Eliminare Righe per ID Multipli (executemany)
Quando hai un elenco di chiavi primarie da rimuovere, usa executemany() per eseguire la stessa istruzione parametrizzata una volta per ciascun elemento in un singolo round-trip:
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() racchiude tutte le singole eliminazioni all'interno di una singola transazione, quindi o tutte riescono o nessuna viene eseguita.
Utilizzo di un Context Manager (Pattern Consigliato)
Aprire la connessione all'interno di un'istruzione with garantisce che venga sempre chiusa, anche se si verifica un'eccezione a metà percorso. Questo è il pattern più pulito per il codice in produzione:
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}")Il blocco with chiude sia il cursore che la connessione all'uscita dal blocco, indipendentemente dal fatto che sia stata sollevata un'eccezione.
Contare le Righe Prima di Eliminare (Dry Run)
Prima di eseguire un DELETE distruttivo, è buona pratica eseguire prima un SELECT COUNT(*) con la stessa clausola WHERE. Questo funge da dry run che ti indica quante righe verranno interessate:
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()Errori Comuni
Dimenticare la clausola WHERE
# DANGER: deletes every row in the table
mycursor.execute("DELETE FROM customers")
mydb.commit()Verifica sempre che la clausola WHERE sia presente e corretta prima di chiamare commit().
Passare una stringa invece di una tupla
# 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",))Non chiamare commit()
mycursor.execute("DELETE FROM customers WHERE name = %s", ("John",))
# Missing mydb.commit() — the deletion will be silently rolled back
# when the connection closesBest Practice
- Usa query parametrizzate (segnaposti
%s) in ogni momento. Non costruire mai stringhe SQL con f-string o concatenazione con+usando dati forniti dall'utente — questo apre una vulnerabilità di SQL injection. - Esegui sempre commit o rollback in modo esplicito. Affidarsi alla chiusura della connessione per annullare una transazione è fonte di confusione; rendi il risultato esplicito nel tuo codice.
- Controlla
rowcountdopo l'eliminazione per confermare che il numero atteso di righe sia stato rimosso. - Usa le transazioni per eliminazioni multi-step. Se devi eliminare righe da più tabelle correlate (ad es., un ordine e le sue voci), racchiudi le operazioni in una singola transazione per non ritrovarti mai con dati orfani.
- Aggiungi indici appropriati sulle colonne usate nelle clausole
WHERE. Un'eliminazione che scansiona l'intera tabella è lenta su dataset di grandi dimensioni.
Capitoli Correlati
- MySQL Get Started — installa il connettore e crea la tua prima connessione
- MySQL Create Table — crea le tabelle da cui eliminerai le righe
- MySQL Insert — aggiungi righe prima di esercitarti a rimuoverle
- MySQL Update — modifica le righe invece di rimuoverle
- MySQL Where — padroneggia la clausola
WHEREusata in tutte le istruzioniDELETE - MySQL Drop Table — rimuovi l'intera struttura di una tabella, non solo le sue righe