Un modelo nos da la estructura bajo la cual va a operar la lógica más grande de nuestra aplicación, aquí es donde le damos un sentido a las diferentes entidades con las cuales debemos contar para poder ejercer nuestras acciones.
Flask tiene la posibilidad de utilizar diferentes tipos de motores de Bases de Datos únicamente utilizando el ORM SQLAlchemy.
Instalar SQLAlchemy
Lo primero que haremos es instalar SQLAlchemy, este paso es muy sencillo, únicamente debemos ejecutar el siguiente comando en la consola habilitada para correr pip:
pip install flask-sqlalchemyAl final obtendremos un mensaje de éxito si todo ha salido de forma correcta:
Crear una aplicación para utilizar SQLAlchemy
Vamos ahora a poner a SQLAlchemy a funcionar, para ello vamos a crear una pequeña aplicación donde veremos cómo podemos establecer una conexión con un motor de Base de Datos. En este caso nuestra aplicación va a llamarse flasko y dentro de ella debemos tener la siguiente estructura.
1- Un archivo llamado ejecutar.py que estará en la raíz de la aplicación, este archivo es el que hace la inicialización básica de todo nuestro entorno.
2- Una carpeta llamada flasko y dentro de esta un archivo llamado __init__.py el cual es donde inicializaremos el uso de flask y de SQLAlchemy directamente.
Veamos en la siguiente imagen como luce esta estructura en un proyecto:
Una vez que ya sabemos que debemos tener vamos a tener los contenidos para nuestros archivos iniciales. En el archivo ejecutar.py debemos tener lo siguiente:
from flasko import appapp.run(debug=True)Luego en nuestro archivo __init__.py vamos a colocar este código:
from flask import Flaskfrom flask.ext.sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://flaskodb.db'db = SQLAlchemy(app)Este último código es muy sencillo de explicar, simplemente importamos Flask, luego importamos SQLAlchemy, establecemos nuestra app para que funcione con el framework y luego establecemos la conexión con nuestra Base de Datos en este caso sqlite, donde el mismo se llamará flaskdb.db y estará en el mismo directorio de nuestra aplicación. Finalmente asignamos el objeto SQLAlchemy a una variable llamada db con la cual trabajaremos luego.
Si ahora iniciamos nuestra aplicación debe arrancar sin errores, lo único es que no tendremos resultado debido a que la aplicación aún está vacía.
Crear el modelo
Ya que tenemos la configuración básica de nuestra aplicación ahora debemos sentar las bases para crear nuestro modelo, para ello vamos a tener que crear una carpeta dentro de nuestra carpeta que contiene el archivo __init__.py y es ahí donde generaremos el contenido necesario.
Veamos cómo se modifica nuestra estructura de carpetas:
Como vemos dentro de nuestra nueva carpeta producto hemos generado 3 archivos, un archivo __init__.py que debe estar vacío, un archivo models.py y otro views.py. Ya con esta estructura vamos a modificar nuestro __init__.py de la raíz de nuestra aplicación, donde es importante no confundir con el __init__.py de productos.
from flask import Flaskfrom flask.ext.sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskodb.db'db = SQLAlchemy(app)from flasko.producto.views import productoapp.register_blueprint(producto)db.create_all()Lo que hemos hecho es que después de la creación del objeto db hemos importado las vistas de nuestra nueva carpeta y hemos registrado un blueprint, finalmente le indicamos al objeto db que debe crear todos las tablas necesarias. Ahora debemos modificar nuestro archivo models.py dentro de producto, y colocaremos el siguiente código:
from flasko import dbclass Producto(db.Model): id = db.Column(db.Integer, primary_key=True) nombre = db.Column(db.String(255)) precio = db.Column(db.Float) def __init__(self, nombre, precio): self.nombre = nombre self.precio = precio def __repr__(self): return '<Producto %d>' % self.idAquí básicamente lo que hacemos es definir una clase la cual va a llevar como atributos los campos que vamos a requerir de nuestro producto, también dentro de ella van un par de métodos para la definición y representación de nuestro modelo.
Una vez cumplido lo anterior pasamos al archivo views.py, en este debemos crear el código que nos permita interactuar con nuestro modelo para ello debemos escribir lo siguiente:
from flask import request, jsonify, Blueprintfrom flasko import app, dbfrom flasko.producto.models import Productoproducto = Blueprint('producto', __name__)@app.route('/')@app.route('/inicio')def inicio(): return "Bienvenido a Flasko"@app.route('/producto/<id>')def producto(id): producto = Producto.query.get_or_404(id) return 'Producto - %s, $%s' % (producto.nombre, producto.precio)@app.route('/productos')def productos(): productos = Producto.query.all() res = {} for producto in productos: res[producto.id] = { 'nombre': producto.nombre, 'precio': str(producto.precio) } return jsonify(res)@app.route('/crear-producto', methods=['POST',])def crear_producto(): nombre = request.form.get('nombre') precio = request.form.get('precio') producto = Producto(nombre, precio) db.session.add(producto) db.session.commit() return 'El producto fue creado con éxito'Lo primero que notamos es que tenemos mucho más contenido en este archivo que en el resto de nuestra aplicación y es porque aquí es donde se desarrolla toda la vida de nuestra vista, la primera ruta es el inicio de nuestra aplicación y no entraña mayor misterio.
La segunda y tercera ruta son de consulta, donde podemos buscar por id de producto y en caso que no haya nada retornar una página 404, también tenemos la funcionalidad para listar todos los productos disponibles en nuestra Base de Datos.
La última ruta es la que nos permite a través del método POST la creación de un producto y su posterior almacenamiento en Base de Datos, para ello instanciamos nuestro modelo Producto, donde luego pasamos dicho atributo al objeto db y con sus métodos add y commit lo añadimos a Base de Datos.
Añadir elementos a nuestra Base de Datos
Ahora lo que resta para probar nuestra aplicación es añadir el contenido que va a ir en nuestra Base de Datos, si recordamos en el archivo views.py creamos una vista que recibe datos a través del método POST y es la que se encarga de hacer las inserciones en la misma. Para añadir elementos vamos a utilizar un módulo de Python llamado requests que nos permite realizar el envío de datos vía POST, si no lo tenemos disponible simplemente debemos instalarlo con el siguiente comando:
pip install requestsEn una consola secundaria vamos a iniciar nuestra aplicación flasko para que el servidor esté arriba y poder enviarle las peticiones desde Python. En nuestra consola interactiva de Python a la cual accedemos al escribir la palabra python, debemos hacer lo siguiente:
requests.post('http://127.0.0.1:5000/crear-producto', data={'nombre':'producto1', 'precio':'50'})Lo que hicimos fue enviar una petición vía POST a nuestra ruta que añade los elementos a la Base de Datos, los parámetros los pasamos en un diccionario Python que es muy similar a un objeto JSON.
Esto nos debe dar un código 200 que quiere decir que hemos efectivamente tenido éxito en nuestra petición, esto lo podemos ver en la siguiente imagen:
Si ahora navegamos a nuestra aplicación en la vista de productos veremos cómo obtenemos lo que acabamos de ingresar por la consola:
Vemos que tenemos un listado en formato JSON con nuestro producto que recién agregamos, si ahora hacemos una búsqueda en la ruta producto/1 veremos que también lo obtendremos:
Por supuesto esto dista mucho de ser algo digno de ser puesto en producción, sin embargo nos ayuda a aprender los fundamentos de modelos y persistencia de datos dentro de Flask, lo más interesante es que como no hemos hecho consultas SQL directas, si cambiamos la conexión a sqlite por una a MySQL por ejemplo, nuestra aplicación seguirá funcionando como si nada.
Con esto hemos finalizado este tutorial, ya sabemos cómo crear modelos en Flask, además que hemos aprendido a manipular de forma básica pero muy útil el ORM SQLAlchemy, donde estos componentes son muy importantes cuando estamos construyendo aplicaciones mucho más grandes ya que nos permitirán lograr resultados más complejos con menos trabajo.