El autor seleccionó el Fondo para el Software Libre y de Código Abierto para recibir una donación como parte del programa Escribe para Donaciones.
Introducción
En las aplicaciones web, generalmente necesitas una base de datos, que es una colección organizada de datos. Utilizas una base de datos para almacenar y mantener datos persistentes que se pueden recuperar y manipular de manera eficiente. Por ejemplo, en una aplicación de redes sociales, tienes una base de datos donde se almacenan los datos de los usuarios (información personal, publicaciones, comentarios, seguidores) de una manera que se puede manipular eficientemente. Puedes agregar datos a una base de datos, recuperarlos, modificarlos o eliminarlos, según diferentes requisitos y condiciones. En una aplicación web, estos requisitos pueden ser un usuario que agrega una nueva publicación, elimina una publicación o elimina su cuenta, lo que podría o no eliminar sus publicaciones. Las acciones que realices para manipular datos dependerán de las características específicas de tu aplicación. Por ejemplo, es posible que no desees que los usuarios agreguen publicaciones sin títulos.
Flask es un marco web ligero de Python que proporciona herramientas y características útiles para crear aplicaciones web en el lenguaje Python. PostgreSQL, o Postgres, es un sistema de gestión de bases de datos relacionales que proporciona una implementación del lenguaje de consulta SQL. Es compatible con los estándares y tiene muchas características avanzadas como transacciones fiables y concurrencia sin bloqueos de lectura.
En este tutorial, construirás una pequeña aplicación web de reseñas de libros que demuestra cómo usar la biblioteca psycopg2
, un adaptador de base de datos PostgreSQL que te permite interactuar con tu base de datos PostgreSQL en Python. Lo usarás con Flask para realizar tareas básicas, como conectar a un servidor de base de datos, crear tablas, insertar datos en una tabla y recuperar datos de una tabla.
Requisitos previos
-
Un entorno de programación Python 3 local. Sigue el tutorial para tu distribución en la serie Cómo instalar y configurar un entorno de programación local para Python 3. En este tutorial, el directorio del proyecto se llama
flask_app
. -
Una comprensión de los conceptos básicos de Flask, como rutas, funciones de vista y plantillas. Si no estás familiarizado con Flask, consulta Cómo Crear Tu Primera Aplicación Web Usando Flask y Python y Cómo Usar Plantillas en una Aplicación Flask.
-
Una comprensión de los conceptos básicos de HTML. Puedes revisar nuestra serie de tutoriales Cómo Construir un Sitio Web con HTML para obtener conocimientos previos.
-
PostgreSQL instalado en su máquina local y acceso al indicador de PostgreSQL. Siga Cómo instalar y usar PostgreSQL en Ubuntu 20.04 para configurar su base de datos PostgreSQL.
Paso 1 — Crear la base de datos y usuario de PostgreSQL
En este paso, creará una base de datos llamada flask_db
y un usuario de base de datos llamado sammy
para su aplicación Flask.
Durante la instalación de Postgres, se creó un usuario del sistema operativo llamado postgres
para corresponder al usuario administrativo postgres
de PostgreSQL. Necesita usar este usuario para realizar tareas administrativas. Puede usar sudo
y pasar el nombre de usuario con la opción -iu
.
Inicie sesión en una sesión interactiva de Postgres usando el siguiente comando:
Se le proporcionará un indicador de PostgreSQL donde puede configurar sus requisitos.
Primero, cree una base de datos para su proyecto:
Nota: Cada declaración de Postgres debe terminar con un punto y coma, así que asegúrate de que tu comando termine con uno si estás experimentando problemas.
A continuación, crea un usuario de base de datos para nuestro proyecto. Asegúrate de seleccionar una contraseña segura:
Luego, otorga a este nuevo usuario acceso para administrar tu nueva base de datos:
Para confirmar que se creó la base de datos, obtén la lista de bases de datos escribiendo el siguiente comando:
Verás flask_db
en la lista de bases de datos.
Cuando hayas terminado, sal del prompt de PostgreSQL escribiendo:
Ahora Postgres está configurado para que puedas conectarte y administrar su información de base de datos a través de Python utilizando la biblioteca psycopg2
. A continuación, instalarás esta biblioteca junto con el paquete Flask.
Paso 2 — Instalando Flask y psycopg2
En este paso, instalarás Flask y la biblioteca psycopg2
para que puedas interactuar con tu base de datos usando Python.
Con tu entorno virtual activado, usa pip
para instalar Flask y la biblioteca psycopg2
:
Una vez que la instalación haya finalizado con éxito, verás una línea similar a la siguiente al final de la salida:
Output
Successfully installed Flask-2.0.2 Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 itsdangerous-2.0.1 psycopg2-binary-2.9.2
Ahora tienes los paquetes requeridos instalados en tu entorno virtual. A continuación, te conectarás y configurarás tu base de datos.
Paso 3 — Configuración de una Base de Datos
En este paso, creará un archivo Python en el directorio de su proyecto flask_app
para conectarse a la base de datos flask_db
, crear una tabla para almacenar libros e insertar algunos libros con reseñas en ella.
Primero, con su entorno de programación activado, abra un archivo nuevo llamado init_db.py
en su directorio flask_app
.
Este archivo abrirá una conexión a la base de datos flask_db
, creará una tabla llamada books
y poblara la tabla utilizando datos de muestra. Agregue el siguiente código:
Guarde y cierre el archivo.
En este archivo, primero importa el módulo os
que utilizará para acceder a las variables de entorno donde almacenará su nombre de usuario y contraseña de la base de datos para que no sean visibles en su código fuente.
Importas la biblioteca psycopg2
. Luego abres una conexión a la base de datos flask_db
utilizando la función psycopg2.connect()
. Especificas el host, que en este caso es localhost. Pasas el nombre de la base de datos al parámetro database
.
Proporcionas tu nombre de usuario y contraseña a través del objeto os.environ
, el cual te da acceso a las variables de entorno que configuraste en tu entorno de programación. Almacenarás el nombre de usuario de la base de datos en una variable de entorno llamada DB_USERNAME
y la contraseña en una variable de entorno llamada DB_PASSWORD
. Esto te permite almacenar tu nombre de usuario y contraseña fuera de tu código fuente, de modo que tu información sensible no se filtre cuando el código fuente se guarde en el control de origen o se cargue en un servidor en internet. Incluso si un atacante obtiene acceso a tu código fuente, no obtendrá acceso a la base de datos.
Creas un cursor llamado cur
utilizando el método connection.cursor()
, que permite que el código Python ejecute comandos PostgreSQL en una sesión de base de datos.
Utiliza el método execute()
del cursor para eliminar la tabla books
si ya existe. Esto evita la posibilidad de que exista otra tabla llamada books
, lo que podría resultar en un comportamiento confuso (por ejemplo, si tiene columnas diferentes). Este no es el caso aquí, porque aún no has creado la tabla, por lo que el comando SQL no se ejecutará. Ten en cuenta que esto eliminará todos los datos existentes cada vez que ejecutes este archivo init_db.py
. Para nuestros propósitos, solo ejecutarás este archivo una vez para iniciar la base de datos, pero es posible que desees ejecutarlo nuevamente para eliminar los datos que hayas insertado y comenzar de nuevo con los datos de muestra iniciales.
Luego utilizas CREATE TABLE books
para crear una tabla llamada books
con las siguientes columnas:
id
: Un ID del tiposerial
, que es un entero autoincrementable. Esta columna representa una clave primaria que especificas usando las palabras clavePRIMARY KEY
. La base de datos asignará un valor único a esta clave para cada entrada.title
: El título del libro del tipovarchar
, que es un tipo de carácter de longitud variable con un límite.varchar (150)
significa que el título puede tener hasta 150 caracteres de longitud.NOT NULL
significa que esta columna no puede estar vacía.author
: El autor del libro, con un límite de 50 caracteres.NOT NULL
significa que esta columna no puede estar vacía.pages_num
: Un entero que representa el número de páginas que tiene el libro.NOT NULL
significa que esta columna no puede estar vacía.revisión
: La revisión del libro. El tipo detexto
significa que la revisión puede ser texto de cualquier longitud.fecha_agregada
: La fecha en que se agregó el libro a la tabla.DEFAULT
establece el valor predeterminado de la columna enCURRENT_TIMESTAMP
, que es el momento en que se agregó el libro a la base de datos. Al igual que conid
, no es necesario especificar un valor para esta columna, ya que se llenará automáticamente.
Después de crear la tabla, utiliza el método execute()
del cursor para insertar dos libros en la tabla, Un Cuento de Dos Ciudades de Charles Dickens, y Anna Karénina de Leo Tolstoy. Utilizas el marcador %s
para pasar los valores a la declaración SQL. psycopg2
maneja la inserción en segundo plano de una manera que previene los ataques de Inyección SQL.
Una vez que termines de insertar datos de libro en tu tabla, utilizas el método connection.commit()
para confirmar la transacción y aplicar los cambios a la base de datos. Luego, limpias las cosas cerrando el cursor con cur.close()
, y la conexión con conn.close()
.
Para que se establezca la conexión con la base de datos, establece las variables de entorno DB_USERNAME
y DB_PASSWORD
ejecutando los siguientes comandos. Recuerda usar tu propio nombre de usuario y contraseña:
Ahora, ejecuta tu archivo init_db.py
en la terminal usando el comando python
:
Una vez que el archivo finalice su ejecución sin errores, se agregará una nueva tabla books
a tu base de datos flask_db
.
Inicia sesión en una sesión interactiva de Postgres para revisar la nueva tabla books
.
Conéctate a la base de datos flask_db
usando el comando \c
:
Luego, usa una instrucción SELECT
para obtener los títulos y autores de los libros de la tabla books
:
Verás una salida como la siguiente:
title | author
----------------------+------------------
A Tale of Two Cities | Charles Dickens
Anna Karenina | Leo Tolstoy
Sal de la sesión interactiva con \q
.
A continuación, crearás una pequeña aplicación Flask, te conectarás a la base de datos, recuperarás las dos reseñas de libros que insertaste en la base de datos y las mostrarás en la página de índice.
Paso 4 — Mostrar Libros
En este paso, crearás una aplicación Flask con una página de índice que recuperará los libros que están en la base de datos y los mostrará.
Con tu entorno de programación activado e Flask instalado, abre un archivo llamado app.py
para editarlo dentro de tu directorio flask_app
:
Este archivo establecerá la conexión con tu base de datos y creará una sola ruta de Flask para usar esa conexión. Agrega el siguiente código al archivo:
Guarda y cierra el archivo.
Aquí importas el módulo os
, la biblioteca psycopg2
, y la clase Flask
y la función render_template()
del paquete flask
. Creas una instancia de la aplicación Flask llamada app
.
Defines una función llamada get_db_connection()
, que abre una conexión a la base de datos flask_db
utilizando el usuario y la contraseña que almacenas en tus variables de entorno DB_USERNAME
y DB_PASSWORD
. La función devuelve el objeto de conexión conn
que usarás para acceder a la base de datos.
Luego creas una ruta principal /
y una función de vista index()
utilizando el decorador app.route()
. En la función de vista index()
, abres una conexión a la base de datos usando la función get_db_connection()
, creas un cursor, y ejecutas la instrucción SQL SELECT * FROM books;
para obtener todos los libros que están en la base de datos. Utilizas el método fetchall()
para guardar los datos en una variable llamada books
. Luego cierras el cursor y la conexión. Por último, retornas una llamada a la función render_template()
para renderizar un archivo de plantilla llamado index.html
pasándole la lista de libros que obtuviste de la base de datos en la variable books
.
Para mostrar los libros que tienes en tu base de datos en la página de índice, primero crearás una plantilla base, que tendrá todo el código HTML básico que otras plantillas también usarán para evitar la repetición de código. Luego crearás el archivo de plantilla index.html
que renderizarás en tu función index()
. Para obtener más información sobre plantillas, consulta Cómo Usar Plantillas en una Aplicación Flask.
Crea un directorio templates
, luego abre una nueva plantilla llamada base.html
:
Agrega el siguiente código dentro del archivo base.html
:
Guarda y cierra el archivo.
Esta plantilla base tiene todo el esquema HTML que necesitarás reutilizar en tus otras plantillas. El bloque title
será reemplazado para establecer un título para cada página, y el bloque content
será reemplazado con el contenido de cada página. La barra de navegación tiene dos enlaces, uno para la página de índice donde usas la función auxiliar url_for()
para enlazar a la función de vista index()
, y el otro para una página Acerca de si decides incluir una en tu aplicación.
A continuación, abre una plantilla llamada index.html
. Esta es la plantilla a la que haces referencia en el archivo app.py
:
Agrega el siguiente código a ella:
Guarda y cierra el archivo.
En este archivo, extiendes la plantilla base y reemplazas el contenido del bloque content
. Utilizas un encabezado <h1>
que también sirve como título.
Utilizas un bucle Jinja for
en la línea {% for book in books %}
para recorrer cada libro en la lista books
. Muestras el ID del libro, que es el primer elemento usando book[0]
. Luego muestras el título del libro, autor, número de páginas, reseña y la fecha en que se agregó el libro.
Mientras estás en el directorio flask_app
con tu entorno virtual activado, dile a Flask sobre la aplicación (app.py
en este caso) usando la variable de entorno FLASK_APP
. Luego establece la variable de entorno FLASK_ENV
en development
para ejecutar la aplicación en modo de desarrollo y tener acceso al depurador. Para obtener más información sobre el depurador de Flask, consulta Cómo manejar errores en una aplicación Flask. Usa los siguientes comandos para hacer esto:
Asegúrate de establecer las variables de entorno DB_USERNAME
y DB_PASSWORD
si aún no lo has hecho:
A continuación, ejecuta la aplicación:
Con el servidor de desarrollo en funcionamiento, visita la siguiente URL utilizando tu navegador:
http://127.0.0.1:5000/
Verás los libros que agregaste a la base de datos en la primera inicialización.
Has mostrado los libros en tu base de datos en la página de índice. Ahora necesitas permitir a los usuarios agregar nuevos libros. Agregarás una nueva ruta para agregar libros en el siguiente paso.
Paso 5 — Agregar Libros Nuevos
En este paso, crearás una nueva ruta para agregar libros y reseñas nuevas a la base de datos.
Agregarás una página con un formulario web donde los usuarios ingresen el título del libro, el autor del libro, el número de páginas y la reseña del libro.
Deja el servidor de desarrollo ejecutándose y abre una nueva ventana de terminal.
Primero, abre tu archivo app.py
:
Para manejar el formulario web, necesitarás importar algunas cosas del paquete flask
:
- El objeto global
request
para acceder a los datos enviados. - La función
url_for()
para generar URL. - La función
redirect()
para redirigir a los usuarios a la página de índice después de agregar un libro a la base de datos.
Agrega estas importaciones en la primera línea del archivo:
Luego agrega la siguiente ruta al final del archivo app.py
:
Guarda y cierra el archivo.
En esta ruta, pasas la tupla ('GET', 'POST')
al parámetro methods
para permitir tanto solicitudes GET como POST. Las solicitudes GET se utilizan para recuperar datos del servidor. Las solicitudes POST se utilizan para enviar datos a una ruta específica. Por defecto, solo se permiten las solicitudes GET. Cuando el usuario solicita por primera vez la ruta /create
utilizando una solicitud GET, se renderizará un archivo de plantilla llamado create.html
. Más tarde editarás esta ruta para manejar solicitudes POST cuando los usuarios completen y envíen el formulario web para agregar nuevos libros.
Abre la nueva plantilla create.html
:
Agrega el siguiente código a ella:
Guarda y cierra el archivo.
Extiendes la plantilla base, estableces un encabezado como título y usas una etiqueta <form>
con el atributo method
establecido en post
para indicar que el formulario enviará una solicitud POST.
Tienes un campo de texto con el nombre title
, que utilizarás para acceder a los datos del título en tu ruta /create
.
Tienes un campo de texto para el autor, un campo de número para el número de páginas y un área de texto para la reseña del libro.
Por último, tienes un botón Enviar al final del formulario.
Ahora, con el servidor de desarrollo en ejecución, usa tu navegador para navegar a la ruta /create
:
http://127.0.0.1:5000/create
Verás una página Agregar un Nuevo Libro con un campo de entrada para el título del libro, uno para su autor, y uno para el número de páginas que tiene el libro, un área de texto para la reseña del libro, y un botón Enviar.
Si completas el formulario y lo envías, enviando una solicitud POST al servidor, no sucede nada porque no has gestionado las solicitudes POST en la ruta /create
.
Abre app.py
para gestionar la solicitud POST que el usuario envía:
Edita la ruta /create
para que se vea de la siguiente manera:
Guarda y cierra el archivo.
Manejas las solicitudes POST dentro de la condición if request.method == 'POST'
. Extraes el título, autor, número de páginas y la reseña que el usuario envía desde el objeto request.form
.
Abres una base de datos utilizando la función get_db_connection()
y creas un cursor. Luego ejecutas una instrucción SQL INSERT INTO
para insertar el título, autor, número de páginas y reseña que el usuario envió en la tabla books
.
Confirmas la transacción y cierras el cursor y la conexión.
Por último, rediriges al usuario a la página de inicio donde pueden ver el libro recién agregado debajo de los libros existentes.
Con el servidor de desarrollo en funcionamiento, usa tu navegador para ir a la ruta /create
:
http://127.0.0.1:5000/create
Completa el formulario con algunos datos y envíalo.
Serás redirigido a la página de inicio donde verás tu nueva reseña de libro.
A continuación, agregarás un enlace a la página de Crear en la barra de navegación. Abre base.html
:
Edita el archivo para que se vea de la siguiente manera:
Guarda y cierra el archivo.
Aquí, agregas un nuevo enlace <a>
a la barra de navegación que apunta a la página de Crear.
Actualiza tu página de índice y verás el nuevo enlace en la barra de navegación.
Ahora tienes una página con un formulario web para agregar nuevas reseñas de libros. Para obtener más información sobre formularios web, consulta Cómo Usar Formularios Web en una Aplicación Flask. Para un método más avanzado y seguro para gestionar formularios web, consulta Cómo Usar y Validar Formularios Web con Flask-WTF.
Conclusión
Has construido una pequeña aplicación web para reseñas de libros que se comunica con una base de datos PostgreSQL. Tienes funcionalidad básica de base de datos en tu aplicación Flask, como agregar nuevos datos a la base de datos, recuperar datos y mostrarlos en una página.
Si deseas leer más sobre Flask, consulta los otros tutoriales en la serie Flask.