MySQL Insert en Python
Aprende a insertar filas individuales, múltiples filas y a gestionar IDs auto-incrementales en MySQL desde Python con mysql-connector-python.
Insertar datos en una tabla MySQL desde Python requiere tres cosas: una conexión activa, una sentencia SQL parametrizada y una llamada a commit(). Este capítulo cubre inserciones de una sola fila, inserciones masivas con executemany(), la recuperación del ID autogenerado de la nueva fila, el manejo de duplicados con ON DUPLICATE KEY UPDATE y los errores típicos que cometen los principiantes.
Requisitos previos
Antes de ejecutar cualquier ejemplo, asegúrate de tener:
- Python 3.x y un servidor MySQL en funcionamiento
mysql-connector-pythoninstalado:
pip install mysql-connector-python- Una base de datos y una tabla
customersya creadas — consulta MySQL Create Database y MySQL Create Table si necesitas configurarlas primero.
Los ejemplos asumen esta definición de tabla:
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255)
);Conexión a MySQL
Toda operación comienza con un objeto de conexión. Pasa tu host, credenciales y nombre de base de datos a mysql.connector.connect(), luego crea un cursor:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()El objeto cursor envía SQL al servidor. Reutiliza la misma conexión para varias sentencias en lugar de reconectarte cada vez.
Insertar una sola fila
Usa la sentencia SQL INSERT INTO con marcadores de posición %s y pasa los valores reales como una tupla. Nunca construyas la cadena de consulta con el operador % o con f-strings de Python — eso expone tu código a inyección 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 = "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()Puntos clave:
%ses la sintaxis de marcador de posición paramysql-connector-pythonindependientemente del tipo de dato de la columna (cadenas de texto, enteros y fechas usan%s).mydb.commit()es obligatorio — sin él, la inserción nunca se escribe en disco. MySQL envuelve las sentencias DML en transacciones implícitas; debes confirmar para finalizarlas.mydb.rollback()en el bloqueexceptdeshace cualquier cambio parcial si la sentencia falla.
Recuperar el ID auto-incremental
Tras una inserción exitosa, mycursor.lastrowid contiene la clave primaria AUTO_INCREMENT que MySQL asignó a la nueva fila:
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()Ejemplo de salida:
Inserted row ID: 1El valor es 0 si la tabla no tiene columna AUTO_INCREMENT. Usa lastrowid para referenciar inmediatamente el nuevo registro en tablas relacionadas (por ejemplo, para insertar una fila correspondiente en una tabla orders).
Insertar múltiples filas
executemany() envía una lista de tuplas de valores en un solo viaje de ida y vuelta al servidor, lo cual es mucho más eficiente que llamar a execute() en un bucle:
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()Ejemplo de salida:
13 records inserted.mycursor.rowcount después de executemany() devuelve el número total de filas afectadas en todas las tuplas.
Cuándo preferir executemany() sobre un bucle
| Enfoque | Viajes de ida y vuelta | Usar cuando |
|---|---|---|
execute() en un bucle | Uno por fila | Las filas dependen de los resultados de las demás |
executemany() | Uno en total | Se insertan filas independientes de forma masiva |
Para conjuntos de datos muy grandes (decenas de miles de filas), considera dividir en lotes de 500–1000 filas para que un único fallo no descarte toda la operación.
Insertar sin fallar ante duplicados
Si tu tabla tiene una restricción UNIQUE e intentas insertar una fila que ya existe, MySQL genera un error de clave duplicada. Hay dos estrategias comunes para evitarlo:
INSERT IGNORE
INSERT IGNORE omite silenciosamente las filas que violan una restricción única:
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 realiza una actualización cuando la clave única ya existe, convirtiendo la sentencia en un "upsert" (insertar o actualizar):
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")Usa ON DUPLICATE KEY UPDATE cuando quieras guardar el valor más reciente independientemente de si la fila era nueva o ya existía.
Insertar datos desde un diccionario
Cuando tus datos llegan como una lista de diccionarios (por ejemplo, desde una carga útil JSON parseada), puedes construir el SQL y los valores de forma dinámica:
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()Los marcadores de posición con nombre (%(name)s) hacen más clara la intención cuando se trabaja con diccionarios y reducen el riesgo de desalinear valores posicionales.
Errores comunes a evitar
Olvidar commit() — La inserción parece funcionar (no hay error) pero no se guardan datos. Llama siempre a mydb.commit() después de las sentencias DML.
Construir SQL con formato de cadena — Usar f-strings o el operador % para incrustar entradas del usuario es la fuente más común de inyección SQL. Pasa siempre los valores como segundo argumento de execute().
Dejar conexiones abiertas — Usa un bloque finally (o un gestor de contexto) para asegurarte de que cursor.close() y mydb.close() siempre se llamen.
Usar INSERT cuando la tabla aún no se ha creado — Obtendrás el error Table 'mydatabase.customers' doesn't exist. Ejecuta primero CREATE TABLE o verifica con SHOW TABLES. Consulta MySQL Create Table.
Qué hacer a continuación
Una vez insertadas las filas, normalmente querrás leerlas. Consulta MySQL Select para consultas SELECT, MySQL Where para filtrar, y MySQL Update para modificar filas existentes.