W3docs

Python MySQL UPDATE – Modifier des lignes dans une table

Apprenez à mettre à jour des lignes MySQL en Python avec mysql-connector-python : requêtes paramétrées, mises à jour en lot, transactions et gestion des erreurs.

Modifier des enregistrements existants est l'une des opérations de base de données les plus courantes. Que vous corrigiez une faute de frappe, mettiez à jour l'adresse d'un client ou marquiez une commande comme expédiée, l'instruction SQL UPDATE est l'outil qu'il vous faut. Ce chapitre vous montre comment exécuter des instructions UPDATE depuis Python avec mysql-connector-python, en couvrant les mises à jour d'une seule ligne, les mises à jour multi-colonnes, les mises à jour en lot avec executemany(), le modèle avec gestionnaire de contexte, ainsi que les erreurs courantes qui piègent les débutants.

Prérequis

Avant d'exécuter les exemples, vous devez disposer des éléments suivants :

  • Python 3.8 ou version ultérieure installé
  • mysql-connector-python installé (pip install mysql-connector-python)
  • Un serveur MySQL en cours d'exécution (local ou distant)
  • Une base de données et une table sur lesquelles travailler (voir MySQL Get Started et MySQL Create Table)

Les exemples ci-dessous supposent que vous disposez d'une base de données appelée mydatabase contenant une table customers créée et remplie dans le chapitre MySQL Insert.

L'instruction UPDATE

L'instruction SQL UPDATE modifie les valeurs d'une ou plusieurs colonnes dans les lignes qui correspondent à une condition :

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

Incluez toujours une clause WHERE. Sans elle, toutes les lignes de la table sont mises à jour. MySQL applique la modification silencieusement — aucune confirmation n'est demandée.

Connexion à MySQL

Avant d'exécuter une instruction, vous devez ouvrir une connexion et créer un curseur. Le curseur envoie le SQL au serveur et récupère les résultats.

import mysql.connector
from mysql.connector import Error

mydb = mysql.connector.connect(
    host="localhost",
    user="yourusername",
    password="yourpassword",
    database="mydatabase"
)

mycursor = mydb.cursor()

Mise à jour d'une seule ligne

La méthode la plus sûre pour cibler une seule ligne consiste à utiliser une requête paramétrée. Passez les valeurs sous forme de tuple Python — le connecteur les échappe avant d'envoyer la requête à MySQL, ce qui prévient les injections SQL.

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 = "UPDATE customers SET address = %s WHERE address = %s"
    val = ("Park Lane 38", "Highway 37")

    mycursor.execute(sql, val)
    mydb.commit()                       # write the change to disk

    print(mycursor.rowcount, "record(s) affected")

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 vous indique combien de lignes ont réellement été modifiées. Une valeur de 0 signifie que la condition WHERE n'a rien correspondu — la requête s'est exécutée sans erreur, mais rien n'a été mis à jour.

Pourquoi commit() est nécessaire

mysql-connector-python ouvre les connexions avec l'autocommit désactivé par défaut. Tant que vous n'appelez pas mydb.commit(), la mise à jour n'existe qu'à l'intérieur de votre transaction courante et est invisible pour les autres connexions. Si le script plante avant le commit, la modification est automatiquement annulée. Appeler mydb.rollback() explicitement dans le bloc except rend l'intention claire.

Mise à jour de plusieurs colonnes à la fois

Séparez les affectations de colonnes par des virgules à l'intérieur de la clause SET pour modifier plusieurs champs en une seule instruction :

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 = "UPDATE customers SET name = %s, address = %s WHERE id = %s"
    val = ("John Smith", "Main Street 10", 1)

    mycursor.execute(sql, val)
    mydb.commit()

    print(mycursor.rowcount, "record(s) affected")

except Error as e:
    print(f"Error: {e}")
    mydb.rollback()

finally:
    if mydb.is_connected():
        mycursor.close()
        mydb.close()

Utiliser la clé primaire (id) dans la clause WHERE est le moyen le plus fiable de cibler exactement une ligne.

Mise à jour de plusieurs lignes en une seule instruction

Si vous souhaitez appliquer la même modification à toutes les lignes correspondant à une condition, élargissez la clause WHERE. Un seul appel à execute() suffit :

import mysql.connector
from mysql.connector import Error

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    # Change the city to "Oslo" for every customer on "Park Lane"
    sql = "UPDATE customers SET address = %s WHERE address LIKE %s"
    val = ("Oslo 1", "%Park Lane%")

    mycursor.execute(sql, val)
    mydb.commit()

    print(mycursor.rowcount, "record(s) affected")

except Error as e:
    print(f"Error: {e}")
    mydb.rollback()

finally:
    if mydb.is_connected():
        mycursor.close()
        mydb.close()

Mise à jour d'une liste de lignes avec executemany()

Lorsque vous avez une liste de lignes à mettre à jour avec des valeurs différentes pour chacune, utilisez executemany(). Il exécute la même instruction paramétrée une fois par élément en un seul aller-retour, en maintenant tout dans une seule transaction :

import mysql.connector
from mysql.connector import Error

# Each tuple: (new_address, customer_id)
updates = [
    ("Sunset Blvd 1",  3),
    ("Baker Street 2", 7),
    ("Abbey Road 3",   11),
]

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    sql = "UPDATE customers SET address = %s WHERE id = %s"
    mycursor.executemany(sql, updates)
    mydb.commit()

    print(mycursor.rowcount, "record(s) affected")

except Error as e:
    print(f"Error: {e}")
    mydb.rollback()

finally:
    if mydb.is_connected():
        mycursor.close()
        mydb.close()

Comme executemany() englobe toutes les mises à jour dans une seule transaction, soit toutes réussissent, soit aucune — vous ne vous retrouvez jamais avec un jeu de données partiellement mis à jour.

Utilisation d'un gestionnaire de contexte (modèle recommandé)

Ouvrir la connexion dans un bloc with garantit qu'elle est toujours fermée, même si une exception est levée en cours de route. C'est le modèle le plus propre pour le code en production :

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 = "UPDATE customers SET address = %s WHERE name = %s"
            mycursor.execute(sql, ("New Road 5", "Alice"))
            mydb.commit()
            print(mycursor.rowcount, "record(s) affected")

except Error as e:
    print(f"Error: {e}")

Le bloc with ferme à la fois le curseur et la connexion à la sortie du bloc, qu'une exception ait été levée ou non.

Prévisualiser les modifications avant la mise à jour (simulation)

Avant d'exécuter une mise à jour qui affecte de nombreuses lignes, exécutez d'abord un SELECT avec la même clause WHERE. Cette simulation vous montre exactement quelles lignes seront modifiées :

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: see which rows would be affected
    mycursor.execute(
        "SELECT id, name, address FROM customers WHERE address LIKE %s",
        (condition,)
    )
    rows = mycursor.fetchall()
    print(f"{len(rows)} row(s) would be updated:")
    for row in rows:
        print(row)

    # Proceed only if rows were found
    if rows:
        mycursor.execute(
            "UPDATE customers SET address = %s WHERE address LIKE %s",
            ("New Highway 1", condition)
        )
        mydb.commit()
        print(f"{mycursor.rowcount} row(s) updated")

except Error as e:
    print(f"Error: {e}")
    mydb.rollback()

finally:
    if mydb.is_connected():
        mycursor.close()
        mydb.close()

Erreurs courantes

Oublier la clause WHERE

# DANGER: updates every row in the table
mycursor.execute("UPDATE customers SET address = %s", ("Wrong Street 1",))
mydb.commit()

Vérifiez toujours que votre clause WHERE est présente et correcte avant d'appeler commit().

Passer une string au lieu d'un tuple

# Wrong — iterates over characters of the string
mycursor.execute("UPDATE customers SET address = %s WHERE name = %s", "AliceMain Street")

# Correct — wrap values in a tuple
mycursor.execute("UPDATE customers SET address = %s WHERE name = %s", ("Main Street", "Alice"))

Le connecteur attend une séquence (tuple ou liste) comme second argument. Passer une string directe l'amène à itérer sur les caractères individuels, ce qui provoque une ProgrammingError déroutante.

Oublier commit()

mycursor.execute("UPDATE customers SET address = %s WHERE name = %s", ("Main Street", "Alice"))
# Missing mydb.commit() — the update is silently rolled back when the connection closes

Appelez mydb.commit() après chaque opération d'écriture, ou définissez autocommit=True sur la connexion si vous souhaitez intentionnellement que chaque instruction soit validée immédiatement.

Utiliser le formatage de string au lieu de requêtes paramétrées

# UNSAFE — vulnerable to SQL injection
name = input("Enter name: ")
sql = f"UPDATE customers SET address = 'New Road' WHERE name = '{name}'"
mycursor.execute(sql)

# Safe — always use %s placeholders
sql = "UPDATE customers SET address = %s WHERE name = %s"
mycursor.execute(sql, ("New Road", name))

Ne construisez jamais des chaînes SQL avec des f-strings ou la concaténation + en utilisant des données fournies par l'utilisateur.

Bonnes pratiques

  • Utilisez des requêtes paramétrées (espaces réservés %s) en permanence. C'est la règle la plus importante — elle prévient les injections SQL.
  • Incluez toujours une clause WHERE et vérifiez-la avant de valider. Une clause WHERE manquante met à jour toutes les lignes de la table.
  • Validez ou annulez explicitement. Se fier à la fermeture de la connexion pour annuler est source de confusion. Rendez le résultat explicite dans votre bloc except.
  • Vérifiez rowcount après la mise à jour pour confirmer que le nombre attendu de lignes a été modifié.
  • Utilisez executemany() pour les mises à jour en lot plutôt que de boucler sur execute(). C'est plus rapide et cela maintient toutes les mises à jour dans une seule transaction.
  • Ajoutez des index sur les colonnes WHERE. Une mise à jour qui parcourt toute la table est lente sur de grands jeux de données. Indexez les colonnes sur lesquelles vous filtrez.
  • Utilisez des transactions pour les mises à jour en plusieurs étapes. Si vous mettez à jour des lignes liées dans plusieurs tables (par exemple, mettre à jour une commande et ses lignes d'articles ensemble), encadrez toutes les instructions dans une seule transaction afin de ne jamais vous retrouver avec des données incohérentes.

Chapitres connexes

  • MySQL Get Started — installez le connecteur et créez votre première connexion
  • MySQL Create Table — créez les tables que vous allez mettre à jour
  • MySQL Insert — ajoutez des lignes avant de vous entraîner à les modifier
  • MySQL Where — maîtrisez la clause WHERE utilisée dans chaque UPDATE
  • MySQL Select — lisez les lignes après les avoir mises à jour pour vérifier le résultat
  • MySQL Delete — supprimez des lignes au lieu de les modifier
  • MySQL Order By — triez les résultats lors de la prévisualisation des lignes avant une mise à jour
Was this page helpful?