Migrar do Pydantic v1 para o Pydantic v2¶
Se você tem uma aplicação FastAPI antiga, pode estar usando o Pydantic versão 1.
O FastAPI tem suporte ao Pydantic v1 ou v2 desde a versão 0.100.0.
Se você tiver o Pydantic v2 instalado, ele será utilizado. Se, em vez disso, tiver o Pydantic v1, será ele que será utilizado.
O Pydantic v1 está agora descontinuado e o suporte a ele será removido nas próximas versões do FastAPI, você deveria migrar para o Pydantic v2. Assim, você terá as funcionalidades, melhorias e correções mais recentes.
Atenção
Além disso, a equipe do Pydantic interrompeu o suporte ao Pydantic v1 para as versões mais recentes do Python, a partir do Python 3.14.
Se quiser usar as funcionalidades mais recentes do Python, você precisará garantir que usa o Pydantic v2.
Se você tem uma aplicação FastAPI antiga com Pydantic v1, aqui vou mostrar como migrá-la para o Pydantic v2 e as novas funcionalidades no FastAPI 0.119.0 para ajudar em uma migração gradual.
Guia oficial¶
O Pydantic tem um Guia de Migração oficial do v1 para o v2.
Ele também inclui o que mudou, como as validações agora são mais corretas e rigorosas, possíveis ressalvas, etc.
Você pode lê-lo para entender melhor o que mudou.
Testes¶
Garanta que você tenha testes para sua aplicação e que os execute na integração contínua (CI).
Assim, você pode fazer a atualização e garantir que tudo continua funcionando como esperado.
bump-pydantic¶
Em muitos casos, quando você usa modelos Pydantic regulares sem personalizações, será possível automatizar a maior parte do processo de migração do Pydantic v1 para o Pydantic v2.
Você pode usar o bump-pydantic da própria equipe do Pydantic.
Essa ferramenta ajuda a alterar automaticamente a maior parte do código que precisa ser modificado.
Depois disso, você pode rodar os testes e verificar se tudo funciona. Se funcionar, está concluído. 😎
Pydantic v1 no v2¶
O Pydantic v2 inclui tudo do Pydantic v1 como um submódulo pydantic.v1.
Isso significa que você pode instalar a versão mais recente do Pydantic v2 e importar e usar os componentes antigos do Pydantic v1 a partir desse submódulo, como se tivesse o Pydantic v1 antigo instalado.
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
size: float
🤓 Other versions and variants
from typing import Union
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
size: float
Suporte do FastAPI ao Pydantic v1 no v2¶
Desde o FastAPI 0.119.0, há também suporte parcial ao Pydantic v1 a partir de dentro do Pydantic v2, para facilitar a migração para o v2.
Assim, você pode atualizar o Pydantic para a versão 2 mais recente e alterar os imports para usar o submódulo pydantic.v1, e em muitos casos tudo simplesmente funcionará.
from fastapi import FastAPI
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
size: float
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item) -> Item:
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
size: float
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item) -> Item:
return item
Atenção
Tenha em mente que, como a equipe do Pydantic não oferece mais suporte ao Pydantic v1 nas versões recentes do Python, a partir do Python 3.14, o uso de pydantic.v1 também não é suportado no Python 3.14 e superiores.
Pydantic v1 e v2 na mesma aplicação¶
Não é suportado pelo Pydantic ter um modelo do Pydantic v2 com campos próprios definidos como modelos do Pydantic v1, ou vice-versa.
graph TB
subgraph "❌ Not Supported"
direction TB
subgraph V2["Pydantic v2 Model"]
V1Field["Pydantic v1 Model"]
end
subgraph V1["Pydantic v1 Model"]
V2Field["Pydantic v2 Model"]
end
end
style V2 fill:#f9fff3
style V1 fill:#fff6f0
style V1Field fill:#fff6f0
style V2Field fill:#f9fff3
...but, you can have separated models using Pydantic v1 and v2 in the same app.
graph TB
subgraph "✅ Supported"
direction TB
subgraph V2["Pydantic v2 Model"]
V2Field["Pydantic v2 Model"]
end
subgraph V1["Pydantic v1 Model"]
V1Field["Pydantic v1 Model"]
end
end
style V2 fill:#f9fff3
style V1 fill:#fff6f0
style V1Field fill:#fff6f0
style V2Field fill:#f9fff3
Em alguns casos, é até possível ter modelos Pydantic v1 e v2 na mesma operação de rota na sua aplicação FastAPI:
from fastapi import FastAPI
from pydantic import BaseModel as BaseModelV2
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
size: float
class ItemV2(BaseModelV2):
name: str
description: str | None = None
size: float
app = FastAPI()
@app.post("/items/", response_model=ItemV2)
async def create_item(item: Item):
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel as BaseModelV2
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
size: float
class ItemV2(BaseModelV2):
name: str
description: Union[str, None] = None
size: float
app = FastAPI()
@app.post("/items/", response_model=ItemV2)
async def create_item(item: Item):
return item
No exemplo acima, o modelo de entrada é um modelo Pydantic v1, e o modelo de saída (definido em response_model=ItemV2) é um modelo Pydantic v2.
Parâmetros do Pydantic v1¶
Se você precisar usar algumas das ferramentas específicas do FastAPI para parâmetros como Body, Query, Form etc. com modelos do Pydantic v1, pode importá-las de fastapi.temp_pydantic_v1_params enquanto conclui a migração para o Pydantic v2:
from typing import Annotated
from fastapi import FastAPI
from fastapi.temp_pydantic_v1_params import Body
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
size: float
app = FastAPI()
@app.post("/items/")
async def create_item(item: Annotated[Item, Body(embed=True)]) -> Item:
return item
🤓 Other versions and variants
from typing import Annotated, Union
from fastapi import FastAPI
from fastapi.temp_pydantic_v1_params import Body
from pydantic.v1 import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
size: float
app = FastAPI()
@app.post("/items/")
async def create_item(item: Annotated[Item, Body(embed=True)]) -> Item:
return item
from typing import Union
from fastapi import FastAPI
from fastapi.temp_pydantic_v1_params import Body
from pydantic.v1 import BaseModel
from typing_extensions import Annotated
class Item(BaseModel):
name: str
description: Union[str, None] = None
size: float
app = FastAPI()
@app.post("/items/")
async def create_item(item: Annotated[Item, Body(embed=True)]) -> Item:
return item
Migre em etapas¶
Dica
Primeiro tente com o bump-pydantic; se seus testes passarem e isso funcionar, então você concluiu tudo com um único comando. ✨
Se o bump-pydantic não funcionar para o seu caso, você pode usar o suporte a modelos Pydantic v1 e v2 na mesma aplicação para fazer a migração para o Pydantic v2 gradualmente.
Você poderia primeiro atualizar o Pydantic para usar a versão 2 mais recente e alterar os imports para usar pydantic.v1 para todos os seus modelos.
Depois, você pode começar a migrar seus modelos do Pydantic v1 para o v2 em grupos, em etapas graduais. 🚶