DEV Community

Maximiliano Burgos
Maximiliano Burgos

Posted on

Diario de Python | #6. Primeros pasos con Color Choice

Ahora que tengo la idea general escrita, voy a avanzar con la ejecución de los primeros pasos del proyecto. En principio necesito un repositorio, así que les voy a mostrar una manera práctica que encontré mediante PyCharm.

GitHub y PyCharm

Primero armo un proyecto en el IDE, lo de siempre:

Color Choice nuevo proyecto

Luego en el menú superior voy a VSC y toco "Share Project on GitHub". Los campos se explican por sí mismos.

Share Project on GitHub

Una vez le doy a share, me pedirá que haga un commit inicial. Esto es necesario para inicializar el branch:

Initial Commit

Con esto, se generará un proyecto en nuestra cuenta. Este es el repositorio que voy a utilizar.

Hola mundo (version API)

Siempre hay que empezar desde lo más simple hasta alcanzar un punto de complejidad, el cual no deja de ser un conjunto funcional de cosas simples interactuando entre ellas.

Por eso, luego de importar los paquetes correspondientes, este es mi hola mundo en FastAPI:

from fastapi import FastAPI, status

app = FastAPI()


@app.get('/', status_code=status.HTTP_200_OK)
async def home():
    return "hello api!"
Enter fullscreen mode Exit fullscreen mode

Debemos correr esto con la configuración de Uvicorn que había comentado en el artículo anterior:

Configuración PyCharm Uvicorn

Y si vemos un "hello api!" en nuestra dirección http://127.0.0.1:8000/, ¡entonces estamos arriba!

Persistencia, o el arte de guardar cosas

La parte más importante de este proyecto va a ser la persistencia: esos usuarios registrados con sus votos deben guardarse en algún lugar.

En el proyecto de la pizzería, utilicé Postgresql y no me terminó de convencer la cantidad de configuración que debía implementar. Quería algo más sencillo y ligero, por lo cual mi opción luego de meditar un buen rato será SQLite.

Por otro lado, para ORM voy a utilizar SQLModel, librería que desarrolló el mismo creador de FastAPI, por lo cual la compatibilidad es absoluta.

Dicho esto, procedo a implementar mi archivo que tendrá las instrucciones para armar la BD:

from sqlmodel import create_engine
import os


BASE_DIR = os.path.dirname(os.path.realpath(__file__))

conn_str = 'sqlite:///' + os.path.join(BASE_DIR, 'color_choice.db')

engine = create_engine(conn_str, echo=True)
Enter fullscreen mode Exit fullscreen mode

Luego voy a crear el archivo que permite ejecutar la creación de mi nueva base de datos (create_db.py):

from sqlmodel import SQLModel
from storage.db import engine

print("CREATING DB.......")

SQLModel.metadata.create_all(engine)
Enter fullscreen mode Exit fullscreen mode

SQLModel utiliza el objeto engine, el cual contiene la información de la BD que vamos a crear, y luego genera la misma. Eso nos da como resultado una BD vacía a modo de archivo que encontraremos en el mismo directorio raíz del proyecto llamada color_choice.db.

Finalmente debemos crear un objeto Session para manejar las transacciones en cada endpoint, por lo cual volvemos a main.py y agregamos:

from storage.db import engine

session = Session(bind=engine)
Enter fullscreen mode Exit fullscreen mode

Los modelos

Para SQLModel, los modelos son la representación de las tablas en nuestra base de datos. De momento no tenemos ninguno, por eso la BD está vacía. Vamos a generar los modelos que nos servirán para gestionar los votos en models.py:

from sqlmodel import SQLModel, Field
from typing import Optional


class Color(SQLModel, table=True):
    color_id: int = Field(default=None, primary_key=True)
    color: str


class Vote(SQLModel, table=True):
    user_id: str = Field(default=None, primary_key=True)
    color_id_selected: Optional[int] = Field(default=None, foreign_key="color.color_id")
    color_voted: bool = Field(default=False)
Enter fullscreen mode Exit fullscreen mode

Al principio pensé en mantener siempre los mismos colores, pero me di cuenta que podía perder escalabilidad. Por lo tanto, decidí crear una tabla para color y otra con los votos que tenga una clave foránea a la anterior. Entonces si un día decido agregar un color, o incluso cambiarle el nombre a uno existente, puedo hacerlo.

Recrear la BD

Ahora que tenemos los modelos armados, hay que volver a generar la BD, pero en el archivo create_db.py vamos a importarlos:

import models
Enter fullscreen mode Exit fullscreen mode

No importa que nuestro IDE diga que el módulo no está en uso, porque en el momento en el que corra create_all(engine) va a considerar automáticamente las clases del modelo. Esto no ocurre por arte de magia, sino que genera tablas de las clases que hereden de SQLModel.

Cuando miremos nuestra BD, ahora tendremos dos tablas: color y vote.

Conclusiones

Todo lo que hicimos constituye un gran avance. Con el proyecto y la BD armados, ya podemos trabajar en los endpoints y la interacción con el usuario. El código, como siempre, pueden encontrarlo en el repositorio del proyecto.

Top comments (0)