Curso de Python / Conectar con MariaDB y gestionar transacciones

Para conectar Python con MariaDB necesitas un controlador, un servidor activo y una cuenta con los permisos adecuados. Este ejemplo utiliza PyMySQL y separa los valores de las instrucciones SQL, con confirmación, reversión y cierre explícitos de la conexión.

Preparar una base y una cuenta limitadas

Ejecuta este SQL desde una conexión administrativa a un servidor local de prácticas. Si ya existen la base o la cuenta indicadas, inspecciona su uso y elige nombres nuevos coherentes con el programa. Sustituye la contraseña de muestra por un secreto local; la aplicación no debe usar una cuenta administradora.

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';

InnoDB aporta transacciones y la cuenta recibe solo lectura, inserción y actualización sobre esta tabla. El identificador externo único permite actualizar el mismo gasto al repetir el ejercicio. Las reglas de transacciones con SQLite ayudan a entender la separación entre almacenamiento, confirmación y duración de la conexión, aunque el servidor y el controlador sean diferentes.

Instalar el controlador y suministrar credenciales

python -m pip install PyMySQL

Guarda el programa del apartado siguiente como mariadb_demo.py antes de ejecutarlo. La conexión TCP utiliza 127.0.0.1, por lo que la parte de host de la cuenta debe corresponder a esa dirección. Si el puerto difiere de 3306, establece MARIADB_PORT con el valor real.

En PowerShell, introduce el secreto sin mostrarlo y retira las variables al 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

En Bash de macOS o Ubuntu puedes utilizar:

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

No escribas contraseñas reales como literales de órdenes ni las imprimas: pueden quedar en historial o registros. Las variables de entorno se heredan por los procesos hijos y no proporcionan todas las garantías de un almacén de secretos. Para servidores remotos, configura TLS, una autoridad de certificación adecuada y verificación de nombre según la referencia de conexión de PyMySQL; cambiar solo la dirección no conserva las condiciones locales.

Ejecutar la conexión y el almacenamiento

Este es el contenido 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()

Con las variables definidas y el servidor preparado, ejecuta:

python mariadb_demo.py

El resultado esperado en ese servidor es ('lunch', 8000). Repetirlo actualiza demo-1 en vez de crear otra transacción. Los importes del ejemplo son unidades completas de KRW.

PyMySQL usa marcadores %s tanto para números como para cadenas. Proporciona los valores en el argumento de execute; no uses interpolación con % ni f-strings para construir el SQL. Los nombres de tablas son estructura y necesitan selección controlada si cambian.

Comprobar fallos y reversión

  1. Prueba una contraseña incorrecta y restaura después el secreto válido.
  2. Prueba un importe negativo y verifica el rechazo de la restricción y la conservación del importe anterior.
  3. Comprueba que la cuenta puede realizar las operaciones concedidas y no otras ajenas al ejercicio.

Diagnostica primero servidor y puerto, después host y contraseña de la cuenta, y finalmente permisos sobre la tabla. No resuelvas un permiso de tabla concediendo acceso a todo el servidor. Si falla connect, todavía no existe una conexión que cerrar. Una reversión de base de datos tampoco deshace archivos o peticiones realizados antes.

Los ejemplos oficiales de PyMySQL explican parámetros y confirmación. La referencia de actualización por clave duplicada de MariaDB precisa el comportamiento de la instrucción utilizada.