반응형

Pydantic의 BaseModel은 Python 데이터의 유효성을 검사하고 관리하기 위한 강력한 도구입니다. JSON 데이터를 파이썬 객체로 변환하거나, API 요청/응답을 검증할 때 특히 유용합니다. 간단한 클래스 정의만으로 복잡한 데이터 검증 로직을 구현할 수 있어요.

BaseModel이 필요한 이유

기존에는 데이터 검증을 이렇게 했습니다.

def validate_user(data: dict):
    if "name" not in data:
        raise ValueError("이름이 필요합니다")
    if not isinstance(data["name"], str):
        raise ValueError("이름은 문자열이어야 합니다")
    if "age" in data and not isinstance(data["age"], int):
        raise ValueError("나이는 정수여야 합니다")
    # 이런 검증이 계속 필요...

BaseModel을 사용하면 훨씬 간단해집니다.

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int | None = None
    email: str

# 자동으로 검증됩니다
user = User(name="김철수", email="kim@example.com")

기본적인 사용법

1. 간단한 모델 정의

from pydantic import BaseModel, EmailStr

class UserProfile(BaseModel):
    username: str
    email: EmailStr
    age: int
    is_active: bool = True  # 기본값 설정

# 데이터 생성과 동시에 검증
user = UserProfile(
    username="python_lover",
    email="python@example.com",
    age=25
)

print(user.username)  # python_lover
print(user.model_dump())  # 딕셔너리로 변환

2. 중첩 모델 사용하기

class Address(BaseModel):
    street: str
    city: str
    postal_code: str

class User(BaseModel):
    name: str
    age: int
    address: Address

# 중첩된 데이터도 자동으로 검증
user = User(
    name="홍길동",
    age=30,
    address={
        "street": "강남대로 123",
        "city": "서울",
        "postal_code": "06000"
    }
)

BaseModel의 강력한 기능들

1. 필드 검증

from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(min_length=1, max_length=50)
    price: float = Field(gt=0)
    description: str | None = Field(default=None)
    tags: list[str] = Field(default_factory=list)

# 잘못된 데이터는 오류 발생
try:
    product = Product(name="", price=-100)
except Exception as e:
    print(f"검증 오류: {e}")

2. 커스텀 검증

from pydantic import BaseModel, validator

class Order(BaseModel):
    quantity: int
    price_per_unit: float
    total_price: float

    @validator('total_price')
    def validate_total_price(cls, v, values):
        if 'quantity' in values and 'price_per_unit' in values:
            expected = values['quantity'] * values['price_per_unit']
            if abs(v - expected) > 0.01:
                raise ValueError('총 가격이 올바르지 않습니다')
        return v

실전 예제: API 응답 처리

from datetime import datetime
from typing import List
from pydantic import BaseModel, Field

class Comment(BaseModel):
    id: int
    content: str
    created_at: datetime
    likes: int = Field(default=0, ge=0)

class BlogPost(BaseModel):
    title: str = Field(min_length=1, max_length=100)
    content: str
    author: str
    tags: List[str] = []
    comments: List[Comment] = []
    published: bool = False
    views: int = Field(default=0, ge=0)

# JSON 데이터를 자동으로 파싱하고 검증
post_data = {
    "title": "Pydantic 사용하기",
    "content": "Pydantic은 정말 유용합니다...",
    "author": "파이썬러버",
    "tags": ["python", "pydantic", "tutorial"],
    "comments": [
        {
            "id": 1,
            "content": "좋은 글이네요!",
            "created_at": "2024-01-11T10:00:00",
            "likes": 5
        }
    ]
}

post = BlogPost(**post_data)

BaseModel의 유용한 메서드들

  1. model_dump(): 모델을 딕셔너리로 변환
    • data_dict = user.model_dump()
  2. model_dump_json(): 모델을 JSON 문자열로 변환
    • json_str = user.model_dump_json()
  3. model_validate(): 딕셔너리에서 모델 생성
    • user = User.model_validate(data_dict)

주의사항

  1. Pydantic v2와 v1의 차이점을 알아야 합니다
  2. 성능에 민감한 경우 검증 비용을 고려해야 합니다
  3. 순환 참조는 피해야 합니다

BaseModel은 특히 다음과 같은 상황에서 매우 유용합니다.

  • FastAPI 등 웹 프레임워크에서 요청/응답 데이터 검증
  • 설정 파일 파싱과 검증
  • 외부 API 응답 데이터 처리
  • 데이터베이스 모델 정의

Pydantic의 BaseModel을 사용하면 데이터 검증 로직을 간단하고 명확하게 작성할 수 있으며, 타입 안전성도 보장받을 수 있습니다.

반응형