W3docs

Python MySQL DELETE – Remover Linhas de uma Tabela

Aprenda a excluir linhas de um banco MySQL em Python com mysql-connector-python, usando consultas parametrizadas, exclusões em lote e tratamento de erros.

Remover registros de um banco de dados MySQL é uma tarefa rotineira em qualquer aplicação Python orientada a dados — seja para limpar sessões expiradas, excluir uma conta de usuário ou arquivar pedidos antigos. Este capítulo mostra como usar a instrução SQL DELETE por meio da biblioteca mysql-connector-python, cobrindo exclusões de linha única, exclusões em lote, consultas parametrizadas seguras, transações e tratamento de erros.

Pré-requisitos

Você precisa do seguinte antes de executar os exemplos:

  • Python 3.8 ou versão posterior instalado
  • mysql-connector-python instalado (pip install mysql-connector-python)
  • Um servidor MySQL em execução (local ou remoto)
  • Um banco de dados e uma tabela para trabalhar (consulte MySQL Get Started e MySQL Create Table)

Os exemplos abaixo assumem que você já tem um banco de dados chamado mydatabase contendo uma tabela customers criada e preenchida no capítulo MySQL Insert.

A Instrução DELETE

A instrução SQL DELETE remove uma ou mais linhas de uma tabela:

DELETE FROM table_name WHERE condition;

Sempre inclua uma cláusula WHERE. Sem ela, todas as linhas da tabela são excluídas. O MySQL não avisa — a tabela inteira é apagada instantaneamente.

Conectando ao MySQL

Antes de executar qualquer instrução, você deve abrir uma conexão e criar um objeto cursor. O cursor é o objeto que envia SQL ao servidor e recupera resultados.

import mysql.connector
from mysql.connector import Error

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

mycursor = mydb.cursor()

Excluindo uma Única Linha

A forma mais segura de direcionar uma linha específica é usar uma consulta parametrizada. Passe o valor como uma tupla Python — o conector substitui o placeholder %s após escapar o valor, o que evita 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 = "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 informa quantas linhas a instrução realmente removeu. Um valor 0 significa que a condição WHERE não correspondeu a nada — a consulta foi executada sem erro, mas nada foi excluído.

Por que commit() é necessário

mysql-connector-python abre conexões no modo autocommit desativado por padrão. Até que você chame mydb.commit(), a exclusão existe apenas dentro da sua transação atual e é invisível para outras conexões. Se o seu script travar antes do commit, a exclusão é revertida automaticamente. Chame mydb.rollback() explicitamente no bloco except para deixar a intenção clara.

Excluindo Múltiplas Linhas com uma Única Instrução

Se você quiser excluir todas as linhas que correspondem a um padrão, mantenha a cláusula WHERE, mas amplie a condição. Apenas uma chamada a execute() é necessária.

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()

Excluindo Linhas por Múltiplos IDs (executemany)

Quando você tem uma lista de chaves primárias para remover, use executemany() para executar a mesma instrução parametrizada uma vez por item em uma única viagem de ida e volta:

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() envolve todas as exclusões individuais dentro de uma única transação, portanto ou todas são bem-sucedidas ou nenhuma é.

Usando um Gerenciador de Contexto (Padrão Recomendado)

Abrir a conexão dentro de uma instrução with garante que ela seja sempre fechada, mesmo que ocorra uma exceção no meio do caminho. Este é o padrão mais limpo para código em produção:

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}")

O bloco with fecha tanto o cursor quanto a conexão quando o bloco termina, independentemente de uma exceção ter sido levantada.

Contando Linhas Antes de Excluir (Execução de Teste)

Antes de executar um DELETE destrutivo, é uma boa prática executar primeiro um SELECT COUNT(*) com a mesma cláusula WHERE. Isso funciona como uma execução de teste que informa quantas linhas serão afetadas:

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()

Erros Comuns

Esquecer a cláusula WHERE

# DANGER: deletes every row in the table
mycursor.execute("DELETE FROM customers")
mydb.commit()

Sempre verifique se a sua cláusula WHERE está presente e correta antes de chamar commit().

Passar uma string em vez de uma 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",))

Não chamar commit()

mycursor.execute("DELETE FROM customers WHERE name = %s", ("John",))
# Missing mydb.commit() — the deletion will be silently rolled back
# when the connection closes

Boas Práticas

  • Use consultas parametrizadas (placeholders %s) sempre. Nunca construa strings SQL com f-strings ou concatenação com + usando dados fornecidos pelo usuário — isso abre uma vulnerabilidade de injeção de SQL.
  • Sempre faça commit ou rollback explicitamente. Depender do fechamento da conexão para reverter uma transação é confuso; deixe o resultado explícito no seu código.
  • Verifique rowcount após a exclusão para confirmar que o número esperado de linhas foi removido.
  • Use transações para exclusões em múltiplas etapas. Se você precisar excluir linhas de várias tabelas relacionadas (por exemplo, um pedido e seus itens), envolva as operações em uma única transação para nunca acabar com dados órfãos.
  • Adicione índices adequados nas colunas usadas nas cláusulas WHERE. Uma exclusão que percorre a tabela inteira é lenta em conjuntos de dados grandes.

Capítulos Relacionados

  • MySQL Get Started — instale o conector e crie sua primeira conexão
  • MySQL Create Table — crie as tabelas das quais você excluirá registros
  • MySQL Insert — adicione linhas antes de praticar a remoção delas
  • MySQL Update — modifique linhas em vez de removê-las
  • MySQL Where — domine a cláusula WHERE usada em todas as instruções DELETE
  • MySQL Drop Table — remova toda a estrutura de uma tabela, não apenas suas linhas
Was this page helpful?