python

Python 3 y MySQL: CRUD y ejemplos de conexión

Introducción

Recientemente vimos cómo trabajar con Python3 y SQLite3. Hoy veremos cómo combinar Python3 y MySQL para insertar, editar, eliminar y mostrar registros en esta base de datos tan popular. Así que veamos este tutorial fácil con ejemplos y demostración.

Para conectar MySQL y Python 3 vamos a utilizar el paquete llamado PyMySQL.

Nota: también he escrito tutoriales para conectar Python con SQL Server y con PostgreSQL.

Descargar el código fuente

Si lo deseas, puedes descargar todos los archivos que contienen el código fuente para conectar Python con MySQL en mi GitHub.

Requisitos

Instalar módulo PyMySQL

Para instalar lo que nos permitirá conectarnos con MySQL desde Python 3 ejecutamos el siguiente comando:

pip install PyMySQL

En caso de que ese comando no llegara a funcionar, podemos usar:

python -m pip install PyMySQL

Si incluso así sigue sin funcionar, recuerda configurar e instalar Python. Cuando instales correctamente la librería, se mostrará algo así:

Instalación de PyMySQL con pip

Crear base de datos en MySQL

Para poder trabajar con Python 3 y MySQL debemos tener una base de datos en éste último. Para ello nos conectamos a nuestro servidor de MySQL y creamos una base de datos. Durante el tutorial trabajaremos con una base de datos de películas que tendrá una tabla llamada también películas, y sólo eso.

En mi caso voy a utilizar la CLI de MySQL. La definición de la tabla y la creación de la base de datos queda así:

CREATE DATABASE peliculas;
USE peliculas;
CREATE TABLE IF NOT EXISTS peliculas(
 id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
 titulo VARCHAR(255) NOT NULL,
 anio SMALLINT NOT NULL,
 PRIMARY KEY(id)
);

Cuando lo ejecuto en la CLI de MySQL se ve así:

Puedes usar phpmyadmin o la interfaz de MySQL workbench, tú decide. Sólo ten en cuenta que la base de datos y la tabla deben estar creadas y funcionando.

Primera conexión

Antes de hacer el CRUD vamos a ver si nos podemos conectar a la base de datos. Para ello ponemos este fragmento de código en un try/except:

import pymysql
try:
 conexion = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='peliculas')
 print("Conexión correcta")
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
 print("Ocurrió un error al conectar: ", e)

Aquí hay unos parámetros que debemos tener en cuenta.

  • host: el host en donde nuestro servidor MySQL escucha. Normalmente es localhost o 127.0.0.1 pero igualmente podría ser otro, basta con poner la ip
  • user: el usuario que puede administrar la base de datos
  • password: la contraseña del usuario. Si está vacía dejamos las comillas vacías
  • db: el nombre de la base de datos a la que intentamos conectarnos

Si todo va bien, al ejecutar el script debe mostrar el mensaje:

Conexión correcta

En caso de que no, se mostrarán errores. Aquí abajo dejo los más comunes.

Errores que podemos encontrar al conectar Python 3 con MySQL

En el primer caso es porque puse localhosts en lugar de localhost. Esto también pasará si ponemos una IP en donde el servidor no esté escuchando.

En el segundo caso puse un usuario que no está registrado o que no tiene permiso para esa base de datos.

El el tercer caso puse el nombre de una base de datos que no existe.

Continuemos entonces.

Insertar datos en MySQL desde Python 3

Antes de continuar cabe mencionar que los ejemplos aquí son 100 % seguros. Es decir, nuestras consultas prevendrán las inyecciones SQL.

Para insertar una película hacemos esto:

import pymysql
try:
 conexion = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='peliculas')
 try:
  with conexion.cursor() as cursor:
   consulta = "INSERT INTO peliculas(titulo, anio) VALUES (%s, %s);"
   #Podemos llamar muchas veces a .execute con datos distintos
   cursor.execute(consulta, ("Volver al futuro 1", 1985))
   cursor.execute(consulta, ("Ready Player One", 2018))
   cursor.execute(consulta, ("It", 2017))
   cursor.execute(consulta, ("Pulp Fiction", 1994))
  conexion.commit()
 finally:
  conexion.close()
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
 print("Ocurrió un error al conectar: ", e)

Como vemos, necesitamos tener la conexión. Y luego usamos un cursor para ejecutar nuestra consulta sobre la misma.

Es importante notar que usamos %s en lugar del valor real, y luego ponemos los verdaderos datos en la llamada a .execute del cursor. Esto es para que sea una consulta segura y las variables sean escapadas en caso de que un usuario malicioso quisiera aprovechar esa vulnerabilidad.

Más abajo hacemos un commit. Esto es para guardar los cambios que hicimos a la base de datos, si no llamamos a este método ninguno de nuestros cambios se reflejará.

Todo eso lo encerramos en un bloque try/finally (aparte del que pertenece a la conexión) y siempre cerramos la conexión. Así, si hay un problema con la inserción, la conexión no quedará abierta.

Consultar datos de MySQL con Python 3

Ya vimos cómo insertar, ahora vamos a ver cómo listar o consultar. Para ello usamos el siguiente código:

import pymysql
try:
 conexion = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='peliculas')
 try:
  with conexion.cursor() as cursor:
   # En este caso no necesitamos limpiar ningún dato
   cursor.execute("SELECT id, titulo, anio FROM peliculas;")
 
   # Con fetchall traemos todas las filas
   peliculas = cursor.fetchall()
 
   # Recorrer e imprimir
   for pelicula in peliculas:
    print(pelicula)
 finally:
  conexion.close()
 
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
 print("Ocurrió un error al conectar: ", e)

Siempre usamos el cursor. Ahora llamamos al método fetchall que traer todas las filas. No deberíamos usarlo para grandes datos, pues si hay 1000 filas traerá todas.

Si quisiéramos traer una por una podríamos llamar al método fetchone. En fin, al ejecutar el script sale esto:

Consultar registros de MySQL con Python 3

Consultar datos de MySQL con Python 3 usando WHERE

Para hacer una consulta con WHERE tenemos que limpiar los datos para prevenir inyecciones. Aquí un ejemplo en donde consultamos las películas cuyo año sea mayor que el 2000.

import pymysql
try:
 conexion = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='peliculas')
 try:
  with conexion.cursor() as cursor:
   
   consulta = "SELECT id, titulo, anio FROM peliculas WHERE anio > %s;"
   cursor.execute(consulta, (2000))
 
   # Con fetchall traemos todas las filas
   peliculas = cursor.fetchall()
 
   # Recorrer e imprimir
   for pelicula in peliculas:
    print(pelicula)
 finally:
  conexion.close()
 
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
 print("Ocurrió un error al conectar: ", e)

Lo que hay que notar es que siempre usamos los placeholders %s en lugar de concatenar valores. Al ejecutar eso, este es el resultado:

Consultar registros de MySQL con Python 3 usando WHERE

Editar filas de MySQL con Python 3

Veamos ahora cómo hacer un update o una edición de datos. Igualmente usaremos el cursor, y prepararemos la sentencia para que la misma sea segura.

Lo que hace el siguiente código es cambiar el nombre a “Ready Player One: comienza el juego” en donde la película tenga el id 2.

import pymysql
try:
 conexion = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='peliculas')
 try:
  with conexion.cursor() as cursor:
   
   consulta = "UPDATE peliculas SET titulo = %s WHERE id = %s;"
   nuevo_titulo = "Ready Player One: comienza el juego"
   id_editar = 2
   cursor.execute(consulta, (nuevo_titulo, id_editar))
 
  # No olvidemos hacer commit cuando hacemos un cambio a la BD
  conexion.commit()
 finally:
  conexion.close()
 
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
 print("Ocurrió un error al conectar: ", e)

Siempre tenemos que usar placeholders, nunca concatenar. Y cuando hacemos una operación que modifique la base de datos (insert, update, delete) tenemos que hacer commit para reflejar los cambios.

En la imagen podemos ver que primero listamos los datos y el título de la película es el antiguo. Luego ejecutamos el script para actualizar, y al volver a listar observamos que la película tiene un nuevo nombre:

Edición o actualización de datos en MySQL con Python 3

Eliminar filas o registros de MySQL con Python 3

Para terminar con este tutorial vamos a ver cómo eliminar datos. Es exactamente igual que cuando hacemos un update o insert.

El siguiente fragmento de código elimina las películas que se hayan estrenado antes del año 2000:

import pymysql
try:
 conexion = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='peliculas')
 try:
  with conexion.cursor() as cursor:
   
   consulta = "DELETE FROM peliculas WHERE anio < %s;"
   anio = 2000
   cursor.execute(consulta, (anio))
 
  # No olvidemos hacer commit cuando hacemos un cambio a la BD
  conexion.commit()
 finally:
  conexion.close()
 
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
 print("Ocurrió un error al conectar: ", e)

Para comprobar que realmente está eliminando primero listamos las películas, luego ejecutamos la eliminación y finalmente volvemos a listar.

Al final sólo quedan 2 películas.

Eliminación de filas, datos o registros de MySQL con Python 3

Conclusión

Así es como terminamos este tutorial de Python 3 y MySQL o MariaDB. Aquí dejo algunas referencias

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

  • Hola, gracias muy buena la información!! quería saber si tienes algo o me puedes recomendar para trabajar mysql desde formularios seria hacer el crud pero desde el navegador web?

  • Gracias Colega. El unico sitio despues de ver 5 y con diferentes librerias que no funcionaban. Tu ejempolo es claro y funciona. Mil gracias amigo. 27.10.22

    • Hola. Usted puede usar cualquier librería o método que prefiera, aquí expongo lo que yo prefiero usar.
      Saludos!

  • Muchísimas gracias por compartir tanta y tan buena información parzibyte.

    Con lo que cuesta mantener un blog!!!
    El tuyo es una maravilla.

  • Buenas Tardes
    Interesante y útil sus apuntes
    Por favor, como haría para vaciar el contenido de una tabla en QT5

    • Hola, simplemente al arreglo de datos hay que volcarlo sobre la tabla. Espero hacer un tutorial sobre ello en el futuro, pues es muy largo de explicar en un comentario.
      Saludos :)

  • muy buen tutorial para conocer algo muy basico pero escencial que tienen todas las aplicaciones, las formas de manejar los datos un una base de datos.

  • Hola,

    Muchísimas gracias, muy interesante. Dos cosas:
    Creo que hay una errata en "Primera conexión" > en la línea 6: "db='peliculass')". Será "db='peliculas')", con una "s", ¿no?

    Y a mi me da un error: Ocurrió un error al conectar: (1049, "Unknown database 'fondos'")
    ¿hay que poner la bdd.tabla? No me sale de ninguna fomra

  • Tantas páginas, videos y cosas vistas, y esta si que es la más completa de todas y sobre todo explica el por qué usar %s en lugar de concatenar. Me gustaría saber si hay forma de poder reutilizar el código así como en php, es decir, hacer un require_once 'db.php' para luego un db = new Conexion , es decir, tener la conexión en un archivo para ser llamada en los diferentes archivos .py donde vaya a manipular datos. Muchas Gracias por tu tiempo y dedicación!!

    • Gracias por tus comentarios :-)
      Nota: el código pierde las tabulaciones al pegarlo aquí, pero sirve para ejemplificar, no lo copies directamente.
      Respondiendo a tu duda, claro que sí, puedes importar tus módulos en Python. Por ejemplo, pega el código de conexión en un archivo llamado base_de_datos.py que residirá junto a tu código principal:

      import pymysql
      def conectar():
      try:
      conexion = pymysql.connect(host='localhost',
      user='root',
      password='',
      db='peliculas')
      return conexion

      except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
      print("Ocurrió un error al conectar: ", e)
      return False

      Ahí definimos a la función conectar. Luego, en tu código principal importa la función y llámala:

      from base_de_datos import conectar
      conexion = conectar()

      La sintaxis es "from tuArchivo import tuFuncion". Ahora ya puedes usar la conexión normalmente, suponiendo que fue exitosa.
      Más información de módulos: https://docs.python.org/2/tutorial/modules.html

Entradas recientes

Tramitar acta de nacimiento en línea de manera instantánea

En este post te quiero compartir mi experiencia tramitando un acta de nacimiento de México…

3 horas hace

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

2 semanas hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esta web usa cookies.