MySQL Insert em Python
Aprenda a inserir linhas únicas, múltiplas linhas e obter IDs auto-incrementados no MySQL com Python usando mysql-connector-python.
Inserir dados em uma tabela MySQL a partir do Python requer três coisas: uma conexão ativa, uma instrução SQL parametrizada e uma chamada a commit(). Este capítulo aborda inserções de linha única, inserções em massa com executemany(), recuperação do ID gerado automaticamente para a nova linha, tratamento de duplicatas com ON DUPLICATE KEY UPDATE e os erros comuns que pegam iniciantes de surpresa.
Pré-requisitos
Antes de executar qualquer exemplo aqui, certifique-se de que você tem:
- Python 3.x e um servidor MySQL em execução
mysql-connector-pythoninstalado:
pip install mysql-connector-python- Um banco de dados e uma tabela
customersjá criados — consulte MySQL Create Database e MySQL Create Table se precisar configurá-los primeiro.
Os exemplos assumem esta definição de tabela:
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255)
);Conectando ao MySQL
Toda operação começa com um objeto de conexão. Passe seu host, credenciais e nome do banco de dados para mysql.connector.connect(), depois crie um cursor:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()O objeto cursor envia SQL ao servidor. Reutilize a mesma conexão para múltiplas instruções em vez de reconectar a cada vez.
Inserindo uma Única Linha
Use a instrução SQL INSERT INTO com marcadores de posição %s e passe os valores reais como uma tupla. Nunca construa a string de consulta com formatação % ou f-string do Python — isso expõe seu código a injeção de 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()Pontos principais:
%sé a sintaxe de marcador de posição paramysql-connector-pythonindependentemente do tipo de dado da coluna (strings, inteiros, datas — todos usam%s).mydb.commit()é obrigatório — sem ele, a inserção nunca é gravada em disco. O MySQL envolve instruções DML em transações implícitas; você deve confirmar para finalizá-las.mydb.rollback()no blocoexceptdesfaz quaisquer alterações parciais se a instrução falhar.
Recuperando o ID Auto-Incrementado
Após uma inserção bem-sucedida, mycursor.lastrowid contém a chave primária AUTO_INCREMENT que o MySQL atribuiu à nova linha:
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()Exemplo de saída:
Inserted row ID: 1O valor é 0 se a tabela não tiver coluna AUTO_INCREMENT. Use lastrowid para referenciar imediatamente o novo registro em tabelas relacionadas (por exemplo, para inserir uma linha correspondente em uma tabela orders).
Inserindo Múltiplas Linhas
executemany() envia uma lista de tuplas de valores em uma única viagem de ida e volta ao servidor, o que é muito mais eficiente do que chamar execute() em um loop:
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()Exemplo de saída:
13 records inserted.mycursor.rowcount após executemany() retorna o número total de linhas afetadas em todas as tuplas.
Quando preferir executemany() em vez de um loop
| Abordagem | Viagens de ida e volta | Use quando |
|---|---|---|
execute() em um loop | Uma por linha | As linhas dependem dos resultados umas das outras |
executemany() | Uma no total | Inserindo linhas independentes em massa |
Para conjuntos de dados muito grandes (dezenas de milhares de linhas), considere dividir em lotes de 500 a 1000 linhas para que uma única falha não descarte toda a operação.
Inserindo Sem Falhar em Duplicatas
Se sua tabela tiver uma restrição UNIQUE e você tentar inserir uma linha que já existe, o MySQL gera um erro de chave duplicada. Duas estratégias comuns evitam isso:
INSERT IGNORE
INSERT IGNORE ignora silenciosamente as linhas que violam uma restrição ú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 uma atualização quando a chave única já existe, tornando a instrução um "upsert" (inserir ou atualizar):
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")Use ON DUPLICATE KEY UPDATE quando quiser que o valor mais recente seja armazenado independentemente de a linha ser nova ou já existente.
Inserindo Dados a Partir de um Dicionário
Quando seus dados chegam como uma lista de dicionários (por exemplo, de um payload JSON analisado), você pode construir o SQL e os valores dinamicamente:
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()Marcadores de posição nomeados (%(name)s) tornam a intenção mais clara quando dicionários estão envolvidos e reduzem o risco de desalinhar valores posicionais.
Erros Comuns a Evitar
Esquecer o commit() — A inserção parece funcionar (sem erro), mas nenhum dado é salvo. Sempre chame mydb.commit() após instruções DML.
Construir SQL com formatação de strings — Usar f-strings ou formatação % para embutir entrada do usuário é a fonte mais comum de injeção de SQL. Sempre passe valores como segundo argumento para execute().
Deixar conexões abertas — Use um bloco finally (ou um gerenciador de contexto) para garantir que cursor.close() e mydb.close() sejam sempre chamados.
Usar INSERT quando a tabela ainda não foi criada — Você receberá um erro Table 'mydatabase.customers' doesn't exist. Execute CREATE TABLE primeiro ou verifique com SHOW TABLES. Consulte MySQL Create Table.
O Que Fazer a Seguir
Depois que suas linhas forem inseridas, você normalmente vai querer lê-las de volta. Consulte MySQL Select para consultas SELECT, MySQL Where para filtragem e MySQL Update para modificar linhas existentes.