반응형
model_config
- 딕셔너리를 사용하여 모델 전체에 대한 설정을 선언
- 모델의 동작 방식, 직렬화/역직렬화 규칙, 필드 처리 방식 등을 제어하는 메타 설정
✅ 기본 예시
class MyModel(BaseModel):
id: int
name: str
model_config = {
"title": "사용자 모델",
"from_attributes": True,
"populate_by_name": True,
}
✅ 주요 model_config 속성과 설명
속성명 | 설명 |
title | 모델의 제목(문서화, OpenAPI 등에서 사용됨) |
description | 모델 설명 |
from_attributes | ✅ ORM 객체나 일반 객체에서 속성 기반으로 필드 값을 추출할 수 있게 함 (from_orm=True 대체) |
populate_by_name | 필드 alias가 있더라도 실제 변수명으로도 값을 넣을 수 있게 허용 |
extra | 모델 정의에 없는 필드에 대해 허용할지 설정 ("ignore", "allow", "forbid") |
str_strip_whitespace | str 필드에서 자동으로 앞뒤 공백 제거 |
str_min_length, str_max_length | 모든 str 필드에 대한 기본 최소/최대 길이 설정 |
validate_default | 필드의 기본값도 유효성 검증할지 여부 |
frozen | 모델을 불변(immutable) 객체로 만듦 (__setattr__ 불가) |
arbitrary_types_allowed | Pydantic이 기본적으로 처리하지 않는 사용자 정의 타입 허용 여부 |
json_encoders | 특정 타입에 대해 JSON 직렬화 방식을 커스터마이징 |
ignored_types | 필드 정의에서 무시할 타입들을 지정 (예: logging.Logger) |
coerce_numbers_to_str | 숫자 값을 문자열로 강제 변환할지 설정 (유연성 vs. 안정성 트레이드오프) |
✅ 자주 사용하는 설정 정리
1. from_attributes: ORM 객체 지원
model_config = {
"from_attributes": True
}
→ MyModel.model_validate(orm_instance) 사용 가능
2. extra: 정의되지 않은 필드 허용 여부
model_config = {
"extra": "ignore" # 또는 "forbid", "allow"
}
- "ignore": 무시
- "forbid": 오류 발생
- "allow": model.extra_fields로 접근 가능
3. frozen: 모델 불변화 (immutable)
model_config = {
"frozen": True
}
→ 생성 후 값 변경 시 TypeError 발생
4. populate_by_name: alias가 있어도 변수명으로 값 할당 허용
class M(BaseModel):
value: int = Field(..., alias="v")
model_config = {
"populate_by_name": True
}
M(value=1) # ✅ 가능
M(v=1) # ✅ 가능
5. json_encoders: 커스텀 직렬화
import datetime
model_config = {
"json_encoders": {
datetime.datetime: lambda v: v.isoformat()
}
}
✅ 전체 예시
from pydantic import BaseModel, Field
from typing import Optional
class UserPayload(BaseModel):
id: int
name: str = Field(..., alias="username")
age: Optional[int]
model_config = {
"from_attributes": True,
"populate_by_name": True,
"extra": "forbid",
"frozen": False,
}
✅ 참고 링크
- 공식 문서: https://docs.pydantic.dev/latest/api/config/
- 모든 설정 속성 보기: pydantic.config.ConfigDict
+ Pydantic 을 활용해 ORM 업데이트하기
Pydantic 모델로 변환된 객체에서 값을 꺼내어 SQLAlchemy ORM 객체에 다시 할당함으로써 업데이트가 가능
단, 명시적으로 값을 꺼내어 user.field = dto.field 형태로 넣어줘야 하며, Pydantic 객체에서 ORM 객체로 자동 반영되는 기능은 없음.
✅ 예시: AgentJobSchema → ORM 객체 업데이트
1. Pydantic 모델 (v2 기준)
from pydantic import BaseModel
class AgentJobSchema(BaseModel):
seq: int
id: str
status: str
job_type: str
model_config = {
"from_attributes": True
}
2. ORM에서 불러오고 → Pydantic으로 로직 처리
agent_job = session.get(AgentJob, job_id)
# Pydantic 객체로 복사 (불변 객체처럼 다룸)
dto = AgentJobSchema.model_validate(agent_job)
# 로직 처리
updated = dto.copy(update={"status": "COMPLETE"})
3. Pydantic → ORM 업데이트 수동 반영
agent_job.status = updated.status
agent_job.job_type = updated.job_type # 필요한 필드만
session.commit()
✅ 자동화하고 싶다면?
방법 1: 간단한 반영 유틸 만들기
def apply_dto_to_model(dto: BaseModel, model, fields: list[str]):
for field in fields:
setattr(model, field, getattr(dto, field))
사용 예:
apply_dto_to_model(updated, agent_job, fields=["status", "job_type"])
방법 2: 전체 필드 일괄 반영 (주의 필요)
for field, value in updated.model_dump().items():
setattr(agent_job, field, value)
- 이 방식은 모든 필드를 무차별적으로 덮어쓰므로, 부분 업데이트에는 적합하지 않음
- 민감한 필드가 있을 경우 사용에 주의
❗ 주의할 점
주의사항 | 설명 |
ORM 객체는 Pydantic 객체가 아님 | 자동 반영 X |
Pydantic 객체는 불변처럼 다루는 게 안전 | 직접 .copy(update=...) 후 반영 |
민감한 필드는 명시적으로 | DTO → ORM 반영 시 반드시 컨트롤할 것 |
✅ 요약
작업 | 가능 여부 | 방법 |
Pydantic → ORM 수동 업데이트 | ✅ 가능 | setattr 또는 수동 할당 |
자동 반영 (DTO 전체 → ORM) | ⚠️ 조심스럽게 가능 | model_dump() + setattr() |
ORM → Pydantic 변환 | ✅ 아주 일반적 | model_validate(orm) |
반응형