Migrating an application on FastAPI from Pydantic V1 to V2

- Andrés Cruz

En español

In this post I wanted to show some changes that need to be made when upgrading the Pydantic package from version 1 to version 2.

 

A common mistake is about the name of the Config class which is now ConfigDict:

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

Is now:

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

 

A common mistake is with the orm_mode attribute to convert to dictionaries between Pydantic and database models, for example SQLALchemy:

 

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

Is now:

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

Another mistake is to define the schemas to indicate the sample data:

* '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"],
            }
        }

Is now:

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"],
            }
        }

While working with SQLAlchemy, there was also an update on the function of:

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

Now it imports from:

from sqlalchemy.orm import sessionmaker, declarative_base

The validator decorator has also changed its name:

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

Is now:

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/

 

For regular expressions it is no longer regex but 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}

Is now:

@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}

Here are some of the changes made to the FastAPI course and book at the project level.

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.