es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Problema de validación de Pydantic al usar paginación con FastApi.

Aquí está mi fragmento de código:

from fastapi_pagination import Page, add_pagination
from fastapi_pagination.ext.sqlalchemy import paginate

@app.get("/clients", response_model=Page[PydanticModel])
def get_items(
    db: Session = Depends(get_db) ) -> Any:

    items = paginate(
        db.query(Model)
        .filter(...)
    )
    ...
    # hacer algunas manipulaciones adicionales ..
    ...
    items.items = new_items
    return items

Cuando especifico Page[PydanticModel] en el response_model, genera un problema con paginate() porque no es el tipo de respuesta final.
El PydanticModel corresponde a new_items y no a items (devuelto por paginate()),

pydantic.error_wrappers.ValidationError: errores de validación para
Page[PydanticModel]

Nota: No quiero usar Page[Any] para mantener una buena documentación de Swagger.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para solucionar este problema, necesitarás crear un nuevo modelo Pydantic que represente el tipo de respuesta final, incluida la manipulación de new_items. Puedes hacer esto creando una nueva clase que herede de la clase Page e incluya un atributo new_items de tipo List[PydanticModel].

    Aquí tienes un ejemplo de cómo puedes modificar el fragmento de código para incluir un modelo Pydantic personalizado:

    from typing import List
    from pydantic import BaseModel
    from fastapi_pagination import Page, add_pagination
    from fastapi_pagination.ext.sqlalchemy import paginate
    
    class CustomPage(Page[PydanticModel]):
        new_items: List[PydanticModel]
    
    @app.get("/clients", response_model=CustomPage)
    def get_items(db: Session = Depends(get_db)) -> Any:
        items = paginate(
            db.query(Model)
            .filter(...)
        )
        # hacer algunas manipulaciones adicionales ...
        new_items = [PydanticModel(**item) for item in items.items]
        # asignar new_items al modelo de página personalizado
        custom_page = CustomPage(
            total=items.total,
            items=items.items,
            new_items=new_items
        )
        return custom_page
    

    En este fragmento de código modificado, primero definimos un nuevo modelo Pydantic llamado CustomPage que hereda de Page[PydanticModel] e incluye un atributo new_items de tipo List[PydanticModel].

    En la función get_items, paginamos el resultado de la consulta y realizamos algunas manipulaciones adicionales para crear nuevas instancias de PydanticModel. Luego creamos una nueva instancia de CustomPage y asignamos los elementos originales a items y los nuevos new_items al atributo correspondiente. Finalmente, devolvemos este objeto de página personalizado.

    De esta manera, podemos seguir utilizando el tipo Page para la documentación de Swagger, al tiempo que incluimos nuestras manipulaciones personalizadas en la respuesta.

Comments are closed.