
Spring Boot에서는 Entity를 DTO로 변환할 때 Builder 패턴이나 팩토리 메서드 패턴을 활용하여 변환 메서드를 직접 구현하는 것이 일반적이다.
하지만 FastAPI에서는 이러한 변환 과정을 간결하게 처리할 수 있는 내장 기능이 제공된다.
Field(from_attribute=True)를 활용하여 ORM 객체를 Pydantic 모델로 자동 변환model_validate()를 사용하여 데이터를 검증하며 DTO로 변환이번 글에서는 FastAPI에서 ORM을 DTO로 변환하는 방법과 장점에 대해 알아본다.
toDto() 같은 변환 메서드를 직접 구현해야 하는 Spring Boot 방식과modl_validate(), from_attribute=True를 활용한 간단한 변환 방식 비교Field(from_attribute=True)를 활용한 방법model_validate()를 활용한 방법Spring Boot에서는 데이터 변환을 직접 수행해야 한다.
FastAPI는 Pydantic의 기능을 활용하여 한 줄로 변환이 가능하다.
@Getter
@AllArgsConstructor
@Builder
public class UserDto {
private Long id;
private String username;
private String email;
public static UserDto fromEntity(UserEntity user) {
return UserDto.builder()
.id(user.getId())
.username(user.getUsername())
.email(user.getEmail())
.build();
}
}
UserDto.fromEntity(userEntity)를 직접 호출해야 변환이 가능Field(from_attribute=True))FastAPI에서는 Pydantic의 Field(from_attribute=True)를 사용하여 ORM을 Schema(Dto)로 변환할 수 있다.
from_attribute는 Pydantic v2에서 도입된 기능으로, 모델 필드를 변환할 때 사용된다.
특히, FastAPI에서 ORM 모델을 Pydantic 모델로 변환할 때 유용하다.
Field(from_attribute=True)를 사용하면, Pydantic이 SQLAlchemy ORM 객체에서 해당 필드를 자동으로 가져와 변환Config.from_attributes = True를 설정하면, 모델 전체에서 자동으로 적용from pydantic import BaseModel, Field
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
# SQLAlchemy ORM 모델
class UserORM(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True)
email = Column(String, unique=True, index=True)
# Pydantic 모델
class UserSchema(BaseModel):
id: int = Field(from_attribute=True)
username: str = Field(from_attribute=True)
email: str = Field(from_attribute=True)
class Config:
from_attributes = True # 전체 모델에서 사용 가능
model_validate())변환 코드 없이 한 줄로 ORM을 DTO로 변환 가능
from pydantic import BaseModel
class UserSchema(BaseModel):
id: int
username: str
email: str
# dict -> Pydantic 모델 변환
user_data = {"id": 1, "username": "fastapi_user", "email": "user@example.com"}
user = UserSchema.model_validate(user_data)
print(user)
# UserSchema(id=1, username='fastapi_user', email='user@example.com')
model_validate()는 Pydantic v2에서 제공하는 객체 검증 메서드이다.
데이터가 Pydantic 모델과 일치하는지 검증하고, 자동 변환을 수행할 수 있다.
model_validate()의 역할
dict, ORM 객체, JSON 등 다양한 데이터 유형을 Pydantic 모델 인스턴스로 변환UserSchema(**data)처럼 직접 인스턴스를 생성하는 것과 동일하지만, 더 유연하고 안전FastAPI에서 SQLAlchemy ORM 객체를 직접 반환하는 것은 비효율적일 수 있음
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(UserORM).filter(UserORM.id == user_id).first()
return user # ❌ ORM 객체 반환 (비효율적)
dict가 아님.@app.get("/users/{user_id}", response_model=UserSchema)
async def get_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(UserORM).filter(UserORM.id == user_id).first()
return UserSchema.model_validate(user) # DTO 변환 후 반환
✅ 이점
from_attribute + model_validate 같이 사용하기이 두 개를 같이 사용하면, ORM 모델에서 Pydantic 모델로 변환하면서 데이터를 검증할 수 있다.
# ORM 객체 생성
user_orm = UserORM(id=1, username="fastapi_user", email="user@example.com")
# Pydantic 모델로 변환 (ORM 객체 검증)
user_schema = UserSchema.model_validate(user_orm)
print(user_schema)
# UserSchema(id=1, username='fastapi_user', email='user@example.com')
from_attribute 덕분에 ORM 모델에서 데이터를 자동으로 매핑model_validate()를 사용해 데이터 검증 및 변환| Spring Boot 방식 | FastAPI 방식 |
|---|---|
toDto() 변환 메서드 필요 | model_validate() 한 줄 변환 |
| Builder 패턴, 팩토리 메서드 사용 | Field(from_attribute=True) 사용 |
| 직접 DTO 객체를 생성해야 함 | ORM을 자동으로 Pydantic 모델로 변환 가능 |
| Lazy loading 문제 해결 필요 | Pydantic이 변환 처리 |
| 기능 | 설명 |
|---|---|
| from_attribute | SQLAlchemy ORM 객체에서 Pydantic 모델로 데이터 변환 |
| model_validate() | 딕셔너리 또는 ORM 객체를 Pydantic 모델로 변환 및 검증 |
Spring Boot에서는 DTO 변환을 직접 해야 하지만, FastAPI는 ORM → DTO 변환을 자동화하는 기능이 내장되어 있어 훨씬 간결하게 구현할 수 있음