반응형

Pydantic의 Field는 BaseModel의 필드를 더 자세하게 정의하고 검증하기 위한 도구입니다. 단순히 타입을 지정하는 것을 넘어서, 데이터의 범위, 형식, 기본값 등을 세밀하게 제어할 수 있게 해줍니다.

Field가 필요한 이유

기본 BaseModel만으로는 이런 제약사항을 표현하기 어려웠습니다.

class Product(BaseModel):
    name: str  # 길이 제한을 어떻게 할까요?
    price: float  # 음수는 어떻게 막을까요?
    stock: int  # 재고가 0 미만이면 안 되는데...

Field를 사용하면 이런 제약사항을 명확하게 표현할 수 있습니다.

from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(min_length=1, max_length=50)
    price: float = Field(gt=0)
    stock: int = Field(ge=0)

Field의 기본 기능들

1. 기본값과 필수값 설정

from pydantic import BaseModel, Field

class User(BaseModel):
    # 필수 필드
    username: str = Field(min_length=3)

    # 기본값이 있는 필드
    is_active: bool = Field(default=True)

    # 기본값을 함수로 설정
    created_at: datetime = Field(default_factory=datetime.now)

    # 선택적 필드
    nickname: str | None = Field(default=None)

2. 숫자 범위 제한

class Score(BaseModel):
    math: int = Field(ge=0, le=100)  # 0 이상 100 이하
    bonus: float = Field(gt=0, lt=10)  # 0 초과 10 미만
    ranking: int = Field(gt=0)  # 양수만 허용

3. 문자열 검증

class Article(BaseModel):
    title: str = Field(
        min_length=1,
        max_length=100,
        pattern="^[A-Za-z0-9 ]*$"  # 영문, 숫자, 공백만 허용
    )
    content: str = Field(min_length=10)
    tags: list[str] = Field(
        default_factory=list,
        max_items=5  # 최대 5개의 태그만 허용
    )

Field의 고급 기능

1. 사용자 정의 검증

from pydantic import BaseModel, Field, validator

def must_be_positive(v: int) -> int:
    if v <= 0:
        raise ValueError("Value must be positive")
    return v

class Order(BaseModel):
    quantity: int = Field(default=1, ge=1)
    price: float = Field(gt=0)
    total: float = Field(default=0.0)

    @validator('total')
    def validate_total(cls, v, values):
        if 'quantity' in values and 'price' in values:
            expected = values['quantity'] * values['price']
            if v != expected:
                raise ValueError(f'Total should be {expected}')
        return v

2. 예제와 설명 추가

class Product(BaseModel):
    name: str = Field(
        description="상품의 이름",
        examples=["맛있는 사과", "신선한 바나나"],
        min_length=1,
        max_length=50
    )
    price: float = Field(
        description="상품의 가격 (원)",
        examples=[1000, 2000],
        gt=0
    )

실전 예제: 복잡한 데이터 모델

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

class Address(BaseModel):
    street: str = Field(min_length=1, max_length=100)
    city: str = Field(min_length=1, max_length=50)
    postal_code: str = Field(
        pattern="^[0-9]{5}$",  # 5자리 숫자만 허용
        description="5자리 우편번호"
    )

class UserProfile(BaseModel):
    username: str = Field(
        min_length=3,
        max_length=20,
        pattern="^[a-zA-Z0-9_-]*$",  # 영문, 숫자, 특수문자(_-)만 허용
        description="사용자 아이디"
    )
    email: EmailStr = Field(description="사용자 이메일")
    age: int = Field(ge=0, lt=150, description="사용자 나이")
    interests: List[str] = Field(
        default_factory=list,
        max_items=10,
        description="관심사 목록 (최대 10개)"
    )
    address: Address
    created_at: datetime = Field(
        default_factory=datetime.now,
        description="계정 생성 시간"
    )

Field 매개변수 총정리

1. 기본값 관련

  • default: 기본값 설정
  • default_factory: 기본값을 반환하는 함수 설정

2. 숫자 제한

  • gt: (Greater Than) 초과
  • ge: (Greater Equal) 이상
  • lt: (Less Than) 미만
  • le: (Less Equal) 이하

3. 문자열 제한

  • min_length: 최소 길이
  • max_length: 최대 길이
  • pattern: 정규식 패턴

4. 컬렉션 제한

  • min_items: 최소 아이템 수
  • max_items: 최대 아이템 수
  • unique_items: 중복 아이템 허용 여부

5. 문서화

  • description: 필드 설명
  • examples: 예시 값
  • title: 필드 제목

사용 시 주의사항

  1. 필드 검증은 런타임에 이루어집니다
  2. 과도한 검증은 성능에 영향을 줄 수 있습니다
  3. 정규식 패턴은 신중하게 사용해야 합니다

Pydantic의 Field를 활용하면 데이터의 유효성을 더욱 정확하고 세밀하게 검증할 수 있으며, 문서화까지 한 번에 처리할 수 있습니다.

반응형