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.

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.