Study/fastapi
pydantic의 orm_model=true, 가상필드, validator 정리
1. orm_mode=True 설정과 사용법
1) 기본 개념
- orm_mode=True를 설정하면, SQLAlchemy ORM 객체를 Pydantic 모델로 변환할 수 있다.
- 일반적으로 BaseModel은 딕셔너리 데이터를 기대하지만, orm_mode를 사용하면 ORM 객체에서도 속성을 추출할 수 있다.
2) 예제 코드 (SQLAlchemy ORM + Pydantic)
from typing import Optional
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from pydantic import BaseModel
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
# ✅ SQLAlchemy 모델 정의
class UserORM(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
email = Column(String, unique=True, index=True)
# ✅ Pydantic 모델 정의
class UserSchema(BaseModel):
id: int
name: str
email: str
class Config:
from_attributes = True # orm_mode=True (FastAPI 최신 버전에서는 from_attributes 사용)
# ✅ ORM 객체를 Pydantic 모델로 변환하는 예제
db = SessionLocal()
user_orm = UserORM(id=1, name="John Doe", email="john@example.com")
user_pydantic = UserSchema.model_validate(user_orm) # ORM 객체를 Pydantic 모델로 변환
print(user_pydantic) # UserSchema(id=1, name='John Doe', email='john@example.com')
2. 가상 필드 (@computed_property) 사용 방법
1) 기본 개념
- Pydantic에서 데이터베이스에 존재하지 않는 "가상 필드"를 추가하려면 computed_property를 사용한다.
- Pydantic 모델의 @property는 동작하지 않음.
- Pydantic v2 → @computed_field 사용
- Pydantic v1 → @root_validator 사용
2) @computed_property 사용 (Pydantic v2)
- Pydantic 2.x에서는 @computed_property를 사용해야 한다.
from pydantic import BaseModel, computed_field
class OrderSchema(BaseModel):
id: int
product_name: str
quantity: int
price: float
is_paid: bool
@computed_field # ✅ Pydantic 2.x에서 사용
def total_price(self) -> float:
return self.quantity * self.price
@computed_field
def payment_status(self) -> str:
return "Paid" if self.is_paid else "Pending"
class Config:
from_attributes = True # ORM 변환 가능
3) @property 대신 @root_validator 사용 (Pydantic v1)
- Pydantic 1.x에서는 @computed_field이 없으므로, @root_validator를 사용해야 한다.
from pydantic import BaseModel, root_validator
class OrderSchema(BaseModel):
id: int
product_name: str
quantity: int
price: float
is_paid: bool
total_price: float
payment_status: str
@root_validator(pre=True)
def calculate_fields(cls, values):
values["total_price"] = values["quantity"] * values["price"]
values["payment_status"] = "Paid" if values["is_paid"] else "Pending"
return values
class Config:
from_attributes = True # ORM 변환 가능
3. 다양한 Validator 사용 방법
- @field_validator를 사용하여 입력 값을 검증합니다.
- @model_validator를 사용하여 여러 필드 간의 관계를 검증할 수 있습니다.
1) 단일 필드 검증 (@field_validator)
from pydantic import field_validator, EmailStr
class UserSchemaValidated(BaseModel):
name: str
email: EmailStr # 기본 이메일 검증 적용
@field_validator("name")
@classmethod
def validate_name(cls, value: str) -> str:
if len(value) < 3:
raise ValueError("이름은 최소 3자 이상이어야 합니다.")
return value
user = UserSchemaValidated(name="John", email="john@example.com")
print(user) # 정상 작동
# 오류 발생 예시
try:
UserSchemaValidated(name="Jo", email="john@example.com") # 이름이 너무 짧음
except ValueError as e:
print(e) # "이름은 최소 3자 이상이어야 합니다."
2) 여러 필드 간 관계 검증 (@model_validator)
from pydantic import model_validator
class UserWithPassword(BaseModel):
password: str
password_confirm: str
@model_validator(mode="before")
@classmethod
def check_passwords(cls, values):
if values["password"] != values["password_confirm"]:
raise ValueError("비밀번호가 일치하지 않습니다.")
return values
# 정상 동작
user = UserWithPassword(password="securepass", password_confirm="securepass")
# 오류 발생 예시
try:
UserWithPassword(password="securepass", password_confirm="wrongpass")
except ValueError as e:
print(e) # "비밀번호가 일치하지 않습니다."
'Study > fastapi' 카테고리의 다른 글
tenacity를 이용한 retry 사용 방법 정리 (0) | 2025.02.04 |
---|---|
[FastAPI] SQLModel의 default와 default_factory의 차이 (0) | 2025.02.03 |
FastAPI에서 settings 사용하는 방법 - pydantic-settings (0) | 2025.01.30 |
[udemy] Complete FastAPI masterclass from scratch 학습 평가 (0) | 2025.01.30 |
[udemy] Complete FastAPI masterclass from scratch - 학습 정리 2 (0) | 2025.01.30 |
댓글