CRUD con Python, Flask y MySQL paso a paso
Vas a construir en tu computador una aplicación web que registra, consulta, edita y elimina los terceros de ContaPyme. La base de datos vive en MySQL (WampServer), el código en Python con Flask y lo escribes en VS Code. Cada paso trae el pantallazo de lo que deberías ver.
- WampServer y phpMyAdmin
- Entorno virtual
- Flask: rutas y plantillas
- mysql-connector
- Consultas parametrizadas
- CRUD completo en la web
Descargar el proyecto terminado (.zip) Úsalo para comparar, no para copiar: la sustentación pide modificarlo en vivo.
Pantallazos. Los que aún no existen aparecen como un recuadro que describe lo que el estudiante debe ver. Para reemplazarlos, guarda tu captura con el nombre que indica el recuadro (visible solo en modo docente) dentro de
assets/img/pasos/. Acepta .webp; si tu captura es .png, cambia la extensión en el atributo src de esta página.Qué vas a construir
Una aplicación web con tres piezas que conversan entre sí. Tu navegador le pide páginas a Flask; Flask ejecuta tu código Python, consulta MySQL y devuelve el HTML ya armado.
app.py recibe cada petición y decide qué hacer. Corre en el puerto 5000contapyme_flask, tabla terceros. Puerto 3306
/ lista y busca (Read). /nuevo crea (Create). /editar/5 actualiza el tercero 5 (Update). /eliminar/5 lo borra (Delete).
Flask necesita un programa de Python encendido todo el tiempo. En tu computador funciona perfecto. En un hosting compartido que solo ejecuta PHP no se puede publicar así: ahí se usa la estrategia A o B del laboratorio 3.
Paso 1. Prepara las herramientas
Comprueba que tienes estas tres cosas antes de seguir:
- Python 3.10 o superior. Abre la terminal (Win y escribe cmd) y ejecuta
python --version. Si Windows abre la tienda o dice que no encuentra el comando, reinstala Python marcando Add python.exe to PATH. - VS Code con la extensión Python de Microsoft. En VS Code: Ctrl+Shift+X, busca Python e instala la de Microsoft.
- WampServer instalado. Trae Apache, PHP, MySQL, MariaDB y phpMyAdmin.
Paso 2. Enciende WampServer
- Abre WampServer desde el menú Inicio y espera a que aparezca su ícono junto al reloj.
- El color del ícono indica el estado: verde, todo encendido; naranja, algún servicio no arrancó; rojo, ninguno.
- Haz clic izquierdo en el ícono. Verás el menú de la imagen. Fíjate en la línea Default DBMS: mysql: significa que MySQL es el motor principal.
WampServer trae los dos motores. MySQL usa el puerto 3306 y MariaDB el 3307. Si creas la base en uno y el programa se conecta al otro, aparece el error Unknown database. En este taller todo va en MySQL, puerto 3306.
Casi siempre es Apache, porque otro programa ocupa el puerto 80. Apache solo hace falta para phpMyAdmin; Flask no lo usa. Clic izquierdo, Apache, Service administration, Test port 80 te dice qué programa lo está usando.
Paso 3. Entra a phpMyAdmin
- En el menú de WampServer, elige PhpMyAdmin, o abre
http://localhost/phpmyadminen el navegador. - Usuario
root, contraseña vacía y, en Elección del servidor, MySQL. - Al entrar, revisa el panel derecho: debe decir Servidor: MySQL (127.0.0.1 via TCP/IP) y el usuario root@localhost.
Es la configuración de fábrica de WampServer y sirve para aprender. Un servidor real nunca se deja así: allí se crea un usuario propio para la aplicación, con contraseña y solo los permisos que necesita.
Paso 4. Crea la base de datos y la tabla
- En phpMyAdmin, pestaña SQL (arriba).
- Pega el script completo y pulsa Continuar, abajo a la derecha.
- Recarga la página. En el panel izquierdo aparece
contapyme_flask; ábrela, entra atercerosy pulsa Examinar. Deben verse tres registros.
Qué hace cada parte: utf8mb4 guarda tildes, eñes y emojis sin dañarlos. AUTO_INCREMENT numera cada tercero solo. UNIQUE en el NIT impide registrar dos veces la misma empresa: es MySQL quien protege el dato, aunque el programa tenga un error. ENUM solo acepta cliente o proveedor.
Paso 5. Crea el proyecto en VS Code
- Crea una carpeta sin espacios ni tildes en la ruta, por ejemplo
C:\proyectos\contapyme-flask. - En VS Code: Archivo, Abrir carpeta, elige esa carpeta y acepta Sí, confío en los autores.
- Crea esta estructura con los íconos de Nuevo archivo y Nueva carpeta del explorador. Los nombres
templatesystaticson obligatorios: Flask los busca exactamente así.
templates y static deben estar al mismo nivel que app.py, no dentro de otra carpeta.Paso 6. Entorno virtual e instalación
Un entorno virtual es una copia de Python solo para este proyecto. Así las librerías de un proyecto no chocan con las de otro.
- Abre la terminal de VS Code: Terminal, Nueva terminal (o Ctrl+ñ).
- Crea el entorno, actívalo e instala las librerías:
El archivo requirements.txt contiene:
- Si todo salió bien, la línea de la terminal empieza con
(venv). - Presiona Ctrl+Shift+P, escribe Python: Select Interpreter y elige el que dice
venv. Así VS Code deja de subrayarflaskcomo si no existiera.
PowerShell bloquea el script que activa el entorno. Ejecuta una sola vez Set-ExecutionPolicy -Scope CurrentUser RemoteSigned, confirma con S y vuelve a activar. Si el equipo es de la sala y no lo permite, cambia la terminal a Command Prompt con la flecha junto al + de la terminal.
(venv) al inicio y Successfully installed al final.Paso 7. La conexión: db.py
Este archivo tiene una sola tarea: abrir conexiones a MySQL. Separarlo de las rutas es la misma idea de capas del laboratorio 3: si mañana cambias de base de datos, solo tocas este archivo.
os.getenv("DB_PASSWORD", "") busca una variable de entorno y, si no existe, usa el valor de la derecha. Con WampServer de fábrica no tienes que cambiar nada. Si tu MySQL tiene contraseña, la defines en la terminal en vez de escribirla en el código, y así no terminas subiéndola a GitHub:
Paso 8. app.py: la aplicación y la validación
Empieza app.py con lo que usan todas las rutas: las importaciones, el objeto app y una función que lee y valida el formulario.
Flask(__name__) crea la aplicación. secret_key es necesaria para los mensajes flash, esos avisos verdes y rojos que aparecen una sola vez después de guardar. leer_formulario devuelve los datos limpios y una lista de errores; si la lista está vacía, los datos son válidos.
En Java harías una clase con @RestController o un Servlet con doGet y doPost. En Flask, una función con el decorador @app.route cumple ese papel.
Paso 9. Leer: listar y buscar (R)
Mira los %s: son los huecos donde mysql-connector pone los valores de forma segura. Nunca armes la consulta pegando texto con f"...{q}...", porque eso abre la puerta a la inyección SQL que viste en el laboratorio 3. dictionary=True hace que cada fila llegue como diccionario, así en la plantilla escribes t.nombre en vez de t[2]. El bloque try/finally garantiza que la conexión se cierra aunque ocurra un error.
Ahora las dos plantillas que usa esta ruta. base.html es el molde común; las demás páginas lo heredan con extends y solo llenan el bloque contenido.
Y la hoja de estilos, para que se vea como en los pantallazos:
Paso 10. Crear (C)
La misma ruta atiende dos momentos: con GET muestra el formulario vacío, con POST recibe lo que el usuario escribió.
con.commit() confirma el cambio: sin esa línea el registro no se guarda. Si MySQL rechaza el NIT porque ya existe, lanza el error 1062 (ER_DUP_ENTRY) y lo convertimos en un mensaje comprensible. Después de guardar se redirige al listado; así, si el usuario recarga la página, no se crea el registro dos veces.
El formulario sirve para crear y para editar. Si recibe un tercero, muestra sus datos; si no, aparece vacío.
Paso 11. Actualizar (U)
<int:id_tercero> toma el número de la dirección: en /editar/2, id_tercero vale 2. Si ese tercero no existe, abort(404) responde "no encontrado" en vez de fallar. Fíjate en el WHERE id=%s del UPDATE: sin él, se modificarían todos los terceros de la tabla.
Paso 12. Eliminar (D) y arrancar la aplicación
Eliminar solo acepta POST. Si fuera un enlace normal (GET), bastaría con abrir una dirección, o que el navegador la precargara, para borrar datos. Por eso en index.html el botón está dentro de un formulario y pide confirmación.
debug=True recarga la aplicación cada vez que guardas un archivo y muestra los errores con detalle. Sirve para desarrollar; en un servidor público se apaga.
Paso 13. Ejecuta y prueba
- Con
(venv)activo, ejecutapython app.py. - La terminal muestra Running on http://127.0.0.1:5000. Mantén Ctrl y haz clic en la dirección.
- Prueba las cuatro operaciones en este orden: busca "pap", crea un tercero, intenta crear otro con el mismo NIT, edita uno y elimina otro.
- Para detener el servidor: Ctrl+C en la terminal.
Paso 14. Comprueba en phpMyAdmin
La prueba definitiva de que el CRUD funciona no es la página web: es la base de datos. Vuelve a phpMyAdmin, abre terceros y pulsa Examinar. El tercero que creaste debe estar allí, con su id y la fecha en creado; el que eliminaste ya no.
Errores frecuentes y su solución
| Mensaje | Causa probable | Solución |
|---|---|---|
ModuleNotFoundError: No module named 'flask' | El entorno virtual no está activo o VS Code usa otro intérprete. | Activa venv (paso 6) y elige su intérprete. |
2003: Can't connect to MySQL server | WampServer apagado o MySQL detenido. | Ícono en verde; clic izquierdo, MySQL, Start service. |
1049: Unknown database 'contapyme_flask' | No ejecutaste el script, o lo ejecutaste en MariaDB. | Repite el paso 4 con el servidor MySQL seleccionado. |
1045: Access denied for user 'root' | Tu root sí tiene contraseña. | Defínela con $env:DB_PASSWORD (paso 7). |
TemplateNotFound: index.html | La carpeta no se llama templates o está en otro nivel. | Revisa la estructura del paso 5. |
| El formulario no cambia de apariencia | El navegador guardó la versión vieja del CSS. | Ctrl+F5 para recargar sin caché. |
Address already in use o el puerto 5000 ocupado | Otra ejecución de la aplicación sigue abierta. | Cierra la otra terminal o usa app.run(debug=True, port=5001). |
Reto y entregable
Reto: agrega el campo ciudad a los terceros. Debe guardarse, mostrarse en el listado y poder editarse. Toca las cuatro capas:
- Base de datos: en phpMyAdmin,
ALTER TABLE terceros ADD ciudad VARCHAR(60) NULL; - Validación: agrega
"ciudad"al diccionario deleer_formulario. - Consultas: incluye la columna en el
INSERTy en elUPDATE, con su%sy su valor en la tupla. - Plantillas: un campo nuevo en
formulario.htmly una columna nueva enindex.html.
Entrega: la carpeta del proyecto comprimida sin la carpeta venv (pesa mucho y se reconstruye con requirements.txt), más un documento con los pantallazos de los pasos 4, 6, 13 y 14 y de la ciudad funcionando.
| Criterio | Superior | Alto | Básico | Bajo |
|---|---|---|---|---|
| CRUD funcionando | Las cuatro operaciones y la búsqueda funcionan | Las cuatro operaciones funcionan | Funcionan listar y crear | No se conecta a la base |
| Reto ciudad | Completo en las cuatro capas | Funciona con un detalle pendiente | Solo en la base o solo en la vista | No lo intentó |
| Seguridad y calidad | Consultas con %s, eliminar por POST, errores manejados | Consultas con %s | Mezcla consultas seguras e inseguras | Concatena texto en el SQL |
| Evidencias | Pantallazos completos y explicados | Pantallazos completos | Faltan algunos | Sin evidencias |
direccion. Quien entendió las cuatro capas lo resuelve en minutos; quien copió el proyecto no sabe por dónde empezar. Revisa además que no entregue la carpeta venv ni contraseñas escritas en db.py.