Pydantic 상속과 타입 어노테이션 활용

2025. 1. 27. 10:41·파이썬/Fast API
반응형

소개

Pydantic은 Python의 타입 어노테이션을 활용하여 데이터 검증을 제공하는 강력한 라이브러리입니다. 이번 글에서는 Pydantic의 다양한 기능과 실전 활용법을 자세히 알아보겠습니다.

기본 모델 구조

BaseModel 상속과 기본 필드 정의

from typing import Annotated
from pydantic import BaseModel, Field
from datetime import datetime
from bson import ObjectId

class BaseItem(BaseModel):
    """
    모든 모델의 기본이 되는 베이스 클래스입니다.
    모든 모델에 공통적으로 필요한 필드를 정의합니다.
    """
    id: Annotated[ObjectId, Field(description="기본 ID")]
    created_at: datetime = Field(
        default_factory=datetime.now,
        description="생성 시간"
    )
    updated_at: datetime = Field(
        default_factory=datetime.now,
        description="수정 시간"
    )

타입 어노테이션과 Field 활용

Field 파라미터의 상세 활용

class ProductItem(BaseItem):
    """
    상품 정보를 나타내는 모델입니다.
    기본 정보 외에 상품 특화 필드를 포함합니다.
    """
    id: Annotated[ObjectId, Field(
        description="상품 고유 식별자",
        alias="product_id"  # API 응답시 필드명 변경
    )]
    name: str = Field(
        min_length=2,
        max_length=50,
        description="상품명 (2-50자)"
    )
    price: float = Field(
        gt=0,
        description="상품 가격 (0보다 큰 값)"
    )
    description: str | None = Field(
        default=None,
        max_length=1000,
        description="상품 설명 (최대 1000자)"
    )
    category: str = Field(
        regex="^[A-Z]{2,10}$",
        description="상품 카테고리 (대문자 2-10자)"
    )

모델 구성과 검증 로직

복잡한 데이터 구조 처리

class Address(BaseModel):
    """
    주소 정보를 나타내는 내부 모델입니다.
    """
    street: str = Field(..., description="도로명 주소")
    city: str = Field(..., description="도시")
    postal_code: str = Field(
        regex="^\d{5}$",
        description="우편번호 (5자리)"
    )
    is_default: bool = Field(
        default=False,
        description="기본 주소 여부"
    )

class UserProfile(BaseModel):
    """
    사용자 프로필을 나타내는 모델입니다.
    주소와 같은 복잡한 중첩 데이터를 포함합니다.
    """
    id: Annotated[ObjectId, Field(alias="user_id")]
    username: str = Field(
        min_length=3,
        max_length=20,
        regex="^[a-zA-Z0-9_-]+$"
    )
    email: str = Field(
        regex="^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
    )
    addresses: list[Address] = Field(
        default_factory=list,
        max_items=5,
        description="최대 5개의 주소 저장 가능"
    )

    @property
    def default_address(self) -> Address | None:
        """기본 주소를 반환하는 프로퍼티"""
        return next(
            (addr for addr in self.addresses if addr.is_default),
            None
        )

검증과 변환 로직 추가

사용자 정의 검증기

from pydantic import validator
from decimal import Decimal

class OrderItem(BaseModel):
    """
    주문 항목을 나타내는 모델입니다.
    가격 계산과 검증 로직을 포함합니다.
    """
    product_id: ObjectId
    quantity: int = Field(gt=0)
    unit_price: Decimal = Field(ge=0)
    total_price: Decimal | None = None

    @validator("quantity")
    def validate_quantity(cls, v: int) -> int:
        if v > 100:
            raise ValueError("한 번에 최대 100개까지만 주문 가능합니다")
        return v

    @validator("total_price", always=True)
    def calculate_total_price(
        cls,
        v: Decimal | None,
        values: dict
    ) -> Decimal:
        """수량과 단가를 기반으로 총 가격을 계산합니다"""
        if "quantity" not in values or "unit_price" not in values:
            raise ValueError("수량과 단가가 필요합니다")

        return values["quantity"] * values["unit_price"]

모델 설정과 메타데이터

Config 클래스 활용

class Product(BaseModel):
    """
    상품 정보 모델입니다.
    상세한 설정과 메타데이터를 포함합니다.
    """
    id: ObjectId
    name: str
    price: Decimal
    stock: int

    class Config:
        # MongoDB ObjectId 사용 허용
        arbitrary_types_allowed = True

        # JSON 변환 규칙 정의
        json_encoders = {
            ObjectId: str,
            Decimal: str
        }

        # 스키마 예제 추가
        schema_extra = {
            "example": {
                "id": "507f1f77bcf86cd799439011",
                "name": "Premium Product",
                "price": "29.99",
                "stock": 100
            }
        }

        # 필드 할당 시 검증 활성화
        validate_assignment = True

실전 사용 예제

# 모델 사용 예시
try:
    user = UserProfile(
        username="john_doe",
        email="john@example.com",
        addresses=[
            Address(
                street="123 Main St",
                city="Seoul",
                postal_code="12345",
                is_default=True
            )
        ]
    )

    # 데이터 검증
    print(user.dict())  # 딕셔너리로 변환
    print(user.json())  # JSON으로 변환
    print(user.default_address)  # 기본 주소 접근

except ValueError as e:
    print(f"유효성 검사 실패: {e}")

마치며

Pydantic의 강력한 타입 시스템과 검증 기능을 활용하면, 안전하고 유지보수하기 쉬운 데이터 모델을 구축할 수 있습니다. 상속과 검증 로직을 적절히 활용하여 재사용 가능한 컴포넌트를 만들어보세요.

저작자표시 비영리 변경금지 (새창열림)

'파이썬 > Fast API' 카테고리의 다른 글

[FastAPI] add_api_route 파라미터  (0) 2025.01.30
[FastAPI] add_api_route로 동적 라우팅 구현  (1) 2025.01.28
[HTTP] 프론트엔드와 백엔드의 데이터 통신 Content-Type  (2) 2025.01.22
[Pydantic] Field로 데이터 유효성 검사 마스터하기  (0) 2025.01.09
FastAPI : 병렬 처리로 API 성능 최적화  (1) 2024.12.04
'파이썬/Fast API' 카테고리의 다른 글
  • [FastAPI] add_api_route 파라미터
  • [FastAPI] add_api_route로 동적 라우팅 구현
  • [HTTP] 프론트엔드와 백엔드의 데이터 통신 Content-Type
  • [Pydantic] Field로 데이터 유효성 검사 마스터하기
코샵
코샵
나의 코딩 일기장
    반응형
  • 코샵
    끄적끄적 코딩 공방
    코샵
    • 분류 전체보기 (545)
      • 상품 추천 (54)
      • MongoDB (4)
      • 하드웨어 (9)
      • 일기장 (4)
      • Unity (138)
        • Tip (41)
        • Project (1)
        • Design Pattern (8)
        • Firebase (6)
        • Asset (2)
      • 파이썬 (128)
        • Basic (41)
        • OpenCV (8)
        • Pandas (15)
        • PyQT (3)
        • SBC(Single Board Computer) (1)
        • 크롤링 (14)
        • Fast API (29)
        • Package (6)
      • Linux (4)
      • C# (97)
        • Algorithm (11)
        • Window (7)
      • TypeScript (50)
        • CSS (10)
      • Git (11)
      • SQL (5)
      • Flutter (10)
        • Tip (1)
      • System (1)
      • BaekJoon (6)
      • Portfolio (2)
      • MacOS (1)
      • 유틸리티 (1)
      • 서비스 (6)
      • 자동화 (3)
      • Hobby (10)
        • 물생활 (10)
        • 식집사 (0)
  • 인기 글

  • 태그

    유니티
    파이썬
    learntocode
    리뷰이관
    devlife
    rtsp
    programming101
    셀레니움
    리스트
    카페24리뷰
    스크립트 실행 순서
    appdevelopment
    믈레코비타멸균우유
    라떼우유
    Python
    codingtips
    programmerlife
    ipcamera
    상품 리뷰 크롤링
    unity
    리뷰관리
    카페24리뷰이관
    쇼핑몰리뷰
    list
    codingcommunity
    긴유통기한우유
    cv2
    스크립트 실행
    C#
    스마트스토어리뷰
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코샵
Pydantic 상속과 타입 어노테이션 활용
상단으로

티스토리툴바