Curso de Python / Conectar ao MariaDB com PyMySQL e controlar transações

Para conectar Python a MariaDB, use um driver e passe os valores separadamente do texto SQL. Esta prática usa PyMySQL e exige um servidor em execução, um banco dedicado e uma conta da aplicação com as permissões necessárias.

Preparar o servidor e uma conta exclusiva de prática

Diferentemente de SQLite, MariaDB usa um processo de servidor separado. Tenha uma instância local de prática disponível e abra sua conexão administrativa para preparar o esquema. Execute o SQL abaixo somente nessa instância. Se o banco ou a conta já existir, confira seu uso e escolha outros nomes de prática, ajustando também o código Python; não substitua recursos de outra aplicação.

A senha mostrada é apenas um marcador: troque-a por um segredo local próprio. A conta administrativa prepara a estrutura; o programa Python usa a conta restrita python_app.

CREATE DATABASE python_lab CHARACTER SET utf8mb4;
CREATE USER 'python_app'@'127.0.0.1' IDENTIFIED BY 'replace-with-a-local-secret';
CREATE TABLE python_lab.expenses (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  external_id VARCHAR(64) NOT NULL UNIQUE,
  name VARCHAR(100) NOT NULL,
  amount BIGINT NOT NULL CHECK(amount >= 0)
) ENGINE=InnoDB;
GRANT SELECT, INSERT, UPDATE ON python_lab.expenses TO 'python_app'@'127.0.0.1';

A tabela usa InnoDB para transações. external_id identifica a transação externa e impede a duplicação dessa identidade; CHECK recusa quantias negativas. A conta recebe SELECT, INSERT e UPDATE somente nesta tabela. Veja as restrições de dados no MariaDB.

A conexão do programa usa TCP em 127.0.0.1. O host da conta foi definido para esse endereço; não suponha que uma conta de outro host terá a mesma correspondência. Confira também a porta: o exemplo usa 3306 por padrão e permite informar outra pela variável MARIADB_PORT.

Instalar o driver e fornecer o segredo na sessão

Selecione o ambiente virtual do projeto e instale o driver externo:

python -m pip install PyMySQL

Salve antecipadamente o programa da próxima seção como mariadb_demo.py, em UTF-8, numa pasta de prática. O ambiente que executa o arquivo precisa conter PyMySQL. Mantenha o usuário e a senha fora do código, do controle de versões e dos logs.

No PowerShell, esta sequência pede a senha sem exibi-la, executa o programa e limpa as variáveis da sessão ao terminar:

$env:MARIADB_USER = "python_app"
$secret = Read-Host "MariaDB password" -AsSecureString
$credential = New-Object System.Net.NetworkCredential("", $secret)
$env:MARIADB_PASSWORD = $credential.Password
python mariadb_demo.py
Remove-Item Env:MARIADB_PASSWORD
Remove-Item Env:MARIADB_USER
Remove-Variable secret, credential

No Bash de macOS ou Ubuntu, a sequência equivalente é:

export MARIADB_USER=python_app
read -r -s -p "MariaDB password: " MARIADB_PASSWORD
printf "\n"
export MARIADB_PASSWORD
python mariadb_demo.py
unset MARIADB_PASSWORD MARIADB_USER

Essas sequências já executam o arquivo: não é necessário repetir o comando se ele acabou de funcionar. No macOS ou Ubuntu, fora de um ambiente virtual, use python3 se esse for o nome do interpretador. Caso uma exceção interrompa a sequência antes da limpeza, confira e remova as variáveis restantes da sessão.

Evite digitar a senha como um valor literal de comando, que pode ficar no histórico. Variáveis de ambiente são transmitidas aos processos filhos e não têm a mesma proteção de um cofre de segredos. O exemplo é local; para um servidor remoto, configure TLS com validação da autoridade certificadora e da identidade do host, conforme as opções de conexão do PyMySQL.

Executar o código completo de conexão e gravação

Conteúdo completo de mariadb_demo.py:

import os
import pymysql

con = pymysql.connect(
    host="127.0.0.1", port=int(os.environ.get("MARIADB_PORT", "3306")),
    user=os.environ["MARIADB_USER"], password=os.environ["MARIADB_PASSWORD"],
    database="python_lab", charset="utf8mb4", autocommit=False,
    connect_timeout=5, read_timeout=5, write_timeout=5,
)
try:
    try:
        with con.cursor() as cur:
            cur.execute("INSERT INTO expenses(external_id,name,amount) VALUES(%s,%s,%s) ON DUPLICATE KEY UPDATE name=VALUES(name), amount=VALUES(amount)", ("demo-1", "lunch", 8000))
        con.commit()
    except Exception:
        con.rollback()
        raise
    with con.cursor() as cur:
        cur.execute("SELECT name,amount FROM expenses WHERE external_id=%s", ("demo-1",))
        print(cur.fetchone())
finally:
    con.close()

Com o ambiente e as variáveis preparados, a chamada do arquivo é:

python mariadb_demo.py

O resultado esperado é ('lunch', 8000). As quantias mantêm a unidade original da prática, won sul-coreano inteiro. O programa insere a identidade demo-1 ou atualiza seu nome e quantia quando essa identidade já existe. Repetir a execução não deve criar outra despesa com o mesmo external_id.

PyMySQL usa posições %s tanto para números quanto para strings. A tupla é o segundo argumento de execute; ela não é aplicada com a operação de formatação % de Python. Também não use uma f-string para incorporar valores à instrução. Nomes de tabelas e colunas são estrutura SQL, não valores; selecione-os de uma lista controlada se precisarem variar.

O cursor é fechado pelo contexto, o commit confirma a escrita e uma exceção nessa etapa provoca rollback antes de ser repassada. O finally fecha a conexão. Se a própria chamada connect falhar, ainda não existe um objeto con para fechar. Os exemplos oficiais do PyMySQL mostram parâmetros e confirmação explícita de transações.

Verificar erros, permissões e recuperação

  1. Execute duas vezes com o servidor preparado e confira que a consulta continua retornando lunch 8000 para demo-1. Uma atualização da mesma identidade não deve aumentar a quantidade de linhas dessa transação.
  2. Experimente uma senha incorreta na sessão para observar a falha de autenticação. Depois restaure o segredo correto sem imprimi-lo.
  3. Numa cópia descartável do programa, troque somente a quantia da inserção de 8000 para -1. A restrição deve rejeitar a escrita; o rollback deve preservar o valor válido anterior. Restaure 8000 e confirme o resultado original.
  4. Com a conta restrita, diferencie operações permitidas de operações recusadas. Não dê permissões gerais no servidor para contornar uma falha de privilégio da tabela.

Investigue primeiro se o servidor e a porta estão acessíveis; depois confira host da conta e autenticação; por último, as permissões no banco e na tabela. Isso distingue falha de rede, de identidade e de autorização, em vez de alterar várias configurações sem conhecer a causa.

O banco reforça regras de armazenamento, mas a aplicação ainda precisa definir unidade, intervalo aceito, tamanho e significado dos dados. O exemplo não é um validador universal de qualquer valor vindo de JSON. Uma migração de esquema ou alteração de permissões exige planejamento próprio em um sistema existente.

Rollback reverte a transação de banco, não arquivos já modificados nem requisições externas já concluídas. A aula de transações em SQLite ilustra essa separação em um banco incorporado, enquanto a aula de exceções e limpeza explica os caminhos de execução e recuperação.