FastAPI에서 Pydantic V2 마이그레이션 후 발생한 이슈 정리

배경

사내 API 서버를 FastAPI 0.111로 업그레이드하면서 Pydantic V2를 적용하게 되었다. 기존 V1 코드가 상당히 많았는데, 단순히 의존성만 올렸다가 런타임 에러를 여러 건 마주쳤다.

주요 변경사항

1. validator → field_validator

기존 @validator 데코레이터가 deprecated 되고 @field_validator로 변경되었다.

# Before (V1)
from pydantic import BaseModel, validator

class User(BaseModel):
    email: str
    
    @validator('email')
    def validate_email(cls, v):
        if '@' not in v:
            raise ValueError('invalid email')
        return v

# After (V2)
from pydantic import BaseModel, field_validator

class User(BaseModel):
    email: str
    
    @field_validator('email')
    @classmethod
    def validate_email(cls, v):
        if '@' not in v:
            raise ValueError('invalid email')
        return v

2. Config 클래스 변경

내부 Config 클래스 방식이 model_config로 변경되었다.

# Before
class User(BaseModel):
    class Config:
        orm_mode = True
        use_enum_values = True

# After
from pydantic import ConfigDict

class User(BaseModel):
    model_config = ConfigDict(
        from_attributes=True,
        use_enum_values=True
    )

orm_modefrom_attributes로 이름이 바뀐 것도 주의해야 한다.

3. json() → model_dump_json()

모델 직렬화 메서드명이 변경되었다.

# Before
user.json()
user.dict()

# After
user.model_dump_json()
user.model_dump()

마이그레이션 전략

V1과 V2를 동시에 지원하는 코드를 작성하려면 PYDANTIC_V2 플래그를 체크하면 된다.

from pydantic import VERSION

PYDANTIC_V2 = VERSION.startswith('2.')

if PYDANTIC_V2:
    from pydantic import field_validator
else:
    from pydantic import validator as field_validator

하지만 장기적으로는 V2로 완전히 전환하는 게 맞다고 판단했다. 성능 개선도 체감할 수 있었고, 타입 체킹이 더 엄격해진 점도 좋았다.

결론

Pydantic V2는 breaking change가 많지만, 공식 마이그레이션 가이드가 잘 되어 있어서 단계적으로 진행하면 어렵지 않았다. 다만 코드베이스가 크다면 충분한 테스트 커버리지를 확보한 후 진행하는 것을 권장한다.