W3docs

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-python instalado:
pip install mysql-connector-python

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:

  • %s es la sintaxis de marcador de posición para mysql-connector-python independientemente 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 bloque except deshace 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: 1

El 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

EnfoqueViajes de ida y vueltaUsar cuando
execute() en un bucleUno por filaLas filas dependen de los resultados de las demás
executemany()Uno en totalSe 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 existed

ON 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.

Was this page helpful?