Cuando trabajas con bases de datos en FastAPI, saber cómo recuperar información es tan importante como saber almacenarla. Aquí aprenderás a consultar todos los registros de una tabla y a filtrar por ID utilizando SQLAlchemy, incluyendo el manejo de respuestas cuando un dato no existe.
¿Cómo consultar todos los datos de una tabla con SQLAlchemy?
Para obtener todos los registros almacenados, el primer paso es crear una instancia de la sesión de base de datos dentro de la función correspondiente. En este caso, se trabaja sobre la función get_movies [01:00].
El proceso es directo:
- Se crea una variable
db como instancia de la sesión.
- Se utiliza el método
db.query() pasándole el modelo de la tabla, en este caso MovieModel.
- Se encadena
.all() para obtener todos los registros.
- El resultado se guarda en una variable llamada
result.
python
db = Session()
result = db.query(MovieModel).all()
Sin embargo, al probar la ruta en la documentación interactiva de FastAPI, aparece un error [02:12]. Esto ocurre porque JsonResponse no puede serializar directamente objetos de tipo MovieModel. La solución es utilizar JSONable Encoder, una utilidad que FastAPI ofrece desde el módulo fastapi.encoders [02:30].
python
from fastapi.encoders import jsonable_encoder
return JSONResponse(content=jsonable_encoder(result))
Con esta conversión, la respuesta devuelve correctamente la lista de películas registradas en la base de datos.
¿Cómo filtrar registros por ID usando el método filter?
El filtrado permite buscar un registro específico en lugar de traer toda la tabla. Para implementarlo, se reemplaza cualquier lógica previa (como un for manual) por una consulta directa con SQLAlchemy [03:15].
Los pasos clave son:
- Crear una sesión de base de datos.
- Ejecutar
db.query(MovieModel) seguido del método .filter().
- Dentro de filter, establecer la condición:
MovieModel.id == id, donde id es el parámetro recibido en la ruta.
- Encadenar
.first() para obtener únicamente el primer resultado que coincida.
python
db = Session()
result = db.query(MovieModel).filter(MovieModel.id == id).first()
El método .first() es fundamental porque retorna un solo objeto en lugar de una lista, lo cual tiene sentido cuando buscas por un identificador único.
¿Qué hacer cuando el registro no existe?
Una buena práctica es validar si el resultado es nulo antes de responder [04:20]. Si no se encuentra el registro, se devuelve un JSONResponse con código de estado 404 y un mensaje descriptivo:
python
if not result:
return JSONResponse(status_code=404, content={"message": "No he encontrado"})
return JSONResponse(status_code=200, content=jsonable_encoder(result))
Es importante no olvidar el return antes del JSONResponse en el caso negativo. Sin él, la función continúa ejecutándose y puede devolver null en lugar del mensaje de error [05:50].
¿Cómo se prueba el filtrado en la documentación de FastAPI?
La documentación interactiva (Swagger UI) permite probar directamente las rutas. Al enviar el ID 1, se obtiene la primera película. Al registrar una segunda película y consultar con ID 2, también funciona correctamente [05:10]. Cuando se envía un ID inexistente, como 3, la API responde con el mensaje "No he encontrado" y el código 404 [06:00].
¿Cuál es el reto de filtrado por categoría?
Como ejercicio práctico, existe una ruta definida para consultar películas por categoría que aún no está implementada [06:20]. El desafío consiste en aplicar la misma lógica de .filter(), pero utilizando el campo de categoría en lugar del ID. La diferencia principal es que este filtro puede devolver múltiples resultados, por lo que conviene usar .all() en lugar de .first().
Si ya dominas la consulta general y el filtrado por ID, este reto es el siguiente paso natural. ¿Cómo resolverías tú el filtrado por categoría? Comparte tu implementación en los comentarios.