pydantic이 뭔지, 왜 쓰는건지 장단점 등을 설명해줘

Pydantic은 Python의 데이터 유효성 검사(validation)와 설정 관리(settings management)를 위한 라이브러리입니다. 주로 FastAPI나 다른 Python 웹 프레임워크에서 많이 사용됩니다.


📌 무엇인가?

Pydantic은 Python의 dataclass와 비슷한 구조를 가지고 있지만, 입력 데이터의 타입을 강제하고 유효성을 검사 합니다. 핵심은 "type hints를 이용해서 런타임에서 실제로 검사한다"는 점입니다.

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str

u = User(id='123', name='Alice')  # id는 str이지만 int로 자동 변환됨
print(u.id)  # 123

🔍 왜 쓰는가?

✅ 목적

  1. 입력 검증 : 외부에서 들어오는 데이터(json 등)를 타입 검증하고 잘못된 값을 막기 위함

  2. 자동 변환 : 가능한 경우 타입을 자동으로 변환

  3. 명확한 구조 정의 : 코드 상에서 데이터 구조를 명확히 표현 가능

  4. 정적 분석 가능 : IDE나 타입 체커가 인식할 수 있음

  5. FastAPI 연동 : FastAPI에서 request body를 검증할 때 거의 필수


👍 장점

1. 타입 기반 검증

타입 힌트를 활용해 런타임에서 오류를 조기에 잡아냄.

2. 자동 형변환

가능하면 타입을 자동으로 맞춰줌. 예: '1'1 (int)

3. 구조화된 에러 메시지

에러가 나면 어디서 어떤 타입이 잘못됐는지 명확하게 알려줌.

4. Nesting 및 재사용성

다른 BaseModel을 중첩해서 사용할 수 있어서 복잡한 구조도 표현 가능.

5. 빠름

내부적으로 Cython을 사용하여 빠르게 동작함 (v2 기준)


👎 단점

1. 러닝커브

단순한 프로젝트에 쓰기에는 문법이나 개념이 복잡할 수 있음

2. 동적 스키마 어려움

스키마가 런타임에서 바뀌는 경우에는 유연하지 않음

3. 성능 이슈 (일부 경우)

대규모 데이터 처리 시 자동 형변환이 오히려 성능 병목이 될 수 있음

4. 에러 추적 어려움 (복잡한 모델일 경우)

중첩 모델이 깊어지면 어느 필드에서 에러 났는지 파악하기 어려울 수 있음


🧠 언제 쓰는 게 적절한가?

  • 외부 입력(json, form, query)을 다루는 API 서버 (FastAPI, Flask 등)

  • 데이터 파이프라인에서 중간 결과를 검증할 때

  • 설정 파일을 로드하고 검증할 때


❗총평

pydantic은 잘 쓰면 생산성과 안정성을 크게 올릴 수 있지만, 단순한 스크립트나 내부 전용 툴에는 과도한 도구일 수도 있습니다. 데이터 유효성 검사가 필요 없다면 굳이 쓸 이유는 없습니다.

궁금한 점 더 있으시면 말씀해주세요.

데이터가 안맞으면 어떻게 돼?

pydantic에서는 데이터가 타입에 맞지 않으면 예외(ValidationError)가 발생합니다. 이건 런타임에서 바로 발생 하고, 명확하게 어떤 필드에 어떤 문제가 있었는지를 알려줍니다.


❌ 예시: 타입이 안 맞을 때

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str

user = User(id='abc', name=123)

이렇게 실행하면 아래와 같은 ValidationError가 발생합니다:

pgsql

pydantic.error_wrappers.ValidationError: 2 validation errors for User
id
  value is not a valid integer (type=type_error.integer)
name
  str type expected (type=type_error.str)

즉, id='abc'는 int로 변환 불가능하고, name=123도 str이 아니기 때문에 에러를 던집니다.


✅ 예시: 자동 변환이 가능한 경우

user = User(id='42', name='Alice')
print(user.id)    # 42 (str → int 자동 변환)
print(user.name)  # 'Alice'

자동 형변환이 가능한 경우에는 문제없이 처리됩니다. 하지만 불가능한 경우는 예외 발생.


예외 처리 방법

물론 try-except로 예외를 잡을 수도 있습니다:

from pydantic import ValidationError

try:
    user = User(id='xyz', name='Bob')
except ValidationError as e:
    print(e.json())

출력 예시:

[
  {
    "loc": ["id"],
    "msg": "value is not a valid integer",
    "type": "type_error.integer"
  }
]

구조화된 JSON 형태로 어떤 필드에 무슨 문제가 있었는지 파악할 수 있습니다.


결론

  • 타입이 안 맞으면 무조건 예외 발생

  • 가능하면 자동 변환

  • ValidationError는 매우 상세하고 디버깅에 유리

  • FastAPI와 연동할 경우, 이 에러는 HTTP 422 응답으로 자동 변환됨

pydantic을 도입하는 주 이유 중 하나가 이 강력하고 친절한 검증 메커니즘 입니다.
더 알고 싶은 부분 있으시면 말씀해주세요.

Categories:

Updated: