Migrando una aplicación en FastAPI de Pydantic V1 a V2

- Andrés Cruz

In english

En esta entrada queria mostrar algunos cambios que hay que realizar al actualizar el paquete de Pydantic de la versión 1 a la 2.

 

Un error común es sobre el nombre de la clase de Config que ahora es ConfigDict:

class Task(MyBaseModel):
    ***
    class ConfigDict:
        ***

Ahora es:

class Task(MyBaseModel):
    ***
    class ConfigDict:
        ***
*  `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0

 

Un error comun es con el atributo de orm_mode para convertir a diccionarios entre los modelos de Pydantic y de la base de datos, por ejemplo SQLALchemy:

 

* 'orm_mode' has been renamed to 'from_attributes'
class Task(MyBaseModel):
    class ConfigDict:
        orm_mode = True

Ahora es:

class Task(MyBaseModel):
    class ConfigDict:
        from_attributes = True

Otro error es para definir los esquemas para indicar los datos de ejemplo:

* 'schema_extra' has been renamed to 'json_schema_extra'
class Task(MyBaseModel):
    ***
    class ConfigDict:
        schema_extra= {
            "example": {
                "id" : 123,
                "name": "Salvar al mundo",
                "description": "Hola Mundo Desc",
                "status": StatusType.PENDING,
                "tag":["tag 1", "tag 2"],
            }
        }

Ahora es:

class Task(MyBaseModel):
    ***
    class ConfigDict:
        json_schema_extra = {
            "example": {
                "id" : 123,
                "name": "Salvar al mundo",
                "description": "Hola Mundo Desc",
                "status": StatusType.PENDING,
                "tag":["tag 1", "tag 2"],
            }
        }

Al trabajar con SQLAlchemy, tambien ocurrió una actualización sobre el la función de:

* MovedIn20Warning: The ``declarative_base()`` function is now available as sqlalchemy.orm.declarative_base(). (deprecated since: 2.0) (Background on SQLAlchemy 2.0

Ahora se importa de:

from sqlalchemy.orm import sessionmaker, declarative_base

El decorador de validator tambien a cambiado de nombre:

from pydantic import BaseModel,  ValidationError, validator

class Task(BaseModel):
   id: int
   name: str
   description: str
   status: StatusType
   
   @validator('id')
   def greater_than_zero(cls, v):
       if v <=0 :
           raise ValueError('must be greater than zero')
       return v

Ahora es:

from pydantic import BaseModel,  ValidationError, field_validator

class Task(BaseModel):
   id: int
   name: str
   description: str
   status: StatusType
   
   @field_validator('id')
   def greater_than_zero(cls, v):
       if v <=0 :
           raise ValueError('must be greater than zero')
       return v
* @validator` validators are deprecated. You should migrate to Pydantic V2 style `@field_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.0.3/migration/

 

Para las expresiones regulares ya no es regex si no pattern:

* DeprecationWarning: `regex` has been depreacated, please use `pattern` instead
    def phone(phone: Annotated[str, Query(regex=r"^(\(?\+[\d]{1,3}\)?)\s?([\d]{1,5})\s?([\d][\s\.-]?){6,7}$", example="+34 111 12-34-56")]):
@app.get("/ep_phone/{phone}") # +34 111 12-34-56
def phone(phone: str = Path(regex=r"^(\(?\+[\d]{1,3}\)?)\s?([\d]{1,5})\s?([\d][\s\.-]?){6,7}$", example="+34 111 12-34-56")):
   return {"phone": phone}

Ahora es:

@app.get("/ep_phone/{phone}") # +34 111 12-34-56
def phone(phone: str = Path(pattern=r"^(\(?\+[\d]{1,3}\)?)\s?([\d]{1,5})\s?([\d][\s\.-]?){6,7}$", example="+34 111 12-34-56")):
   return {"phone": phone}

Estos son algunos de los cambios realizados en el curso y libro sobre FastAPI a nivel del proyecto.

Acepto recibir anuncios de interes sobre este Blog.

Hablaremos sobre algunos cambios que debemos de realizar al actualizar un proyecto en FastAPI de Pydantic 1 a 2.

- Andrés Cruz

In english