본문으로 건너뛰기
백엔드 기초집: Python FastAPILESSON 16

CRUD(Update, Delete)와 데이터 검증

난이도초급
예상 시간35분
선수지식이전 강의

16강. CRUD(Update, Delete)와 데이터 검증

1. 이번 강의에서 해결할 문제

잘못 입력한 게임 이름과 점수를 고치거나 기록을 삭제할 수 없습니다. 선택 필드가 있는 PATCH 모델과 트랜잭션 처리로 CRUD를 완성합니다.

2. 학습 목표

3. 핵심 개념

PATCH 본문에서는 모든 필드가 선택이지만 값이 전혀 없는 요청은 의미가 없습니다. Pydantic의 model_fields_set으로 전송 여부를 확인하고 model_dump(exclude_unset=True)로 실제 입력만 꺼냅니다. DB 변경은 commit 전까지 트랜잭션 안에 있으며 오류가 나면 rollback해야 Session을 다시 쓸 수 있습니다.

4. 단계별 코드 예시

파일 경로: game-ranking-api/app/schemas/record.py

app/schemas/record.py
from pydantic import BaseModel, Field, model_validator


class RecordUpdate(BaseModel):
game_name: str | None = Field(default=None, min_length=1, max_length=80)
score: int | None = Field(default=None, ge=0, le=1_000_000)

@model_validator(mode="after")
def require_change(self) -> "RecordUpdate":
if not self.model_fields_set:
raise ValueError("수정할 필드를 하나 이상 보내세요")
return self

파일 경로: game-ranking-api/app/routers/records.py

app/routers/records.py
from fastapi import HTTPException, Response, status


@router.patch("/{record_id}", response_model=RecordRead)
def update_record(record_id: int, payload: RecordUpdate, db: DbSession) -> GameRecord:
record = db.get(GameRecord, record_id)
if record is None:
raise HTTPException(status_code=404, detail="기록을 찾을 수 없습니다")

for field, value in payload.model_dump(exclude_unset=True).items():
setattr(record, field, value)

try:
db.commit()
except Exception:
db.rollback()
raise
db.refresh(record)
return record


@router.delete("/{record_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_record(record_id: int, db: DbSession) -> Response:
record = db.get(GameRecord, record_id)
if record is None:
raise HTTPException(status_code=404, detail="기록을 찾을 수 없습니다")
db.delete(record)
db.commit()
return Response(status_code=status.HTTP_204_NO_CONTENT)

실행 위치: game-ranking-api/

python -m uvicorn app.main:app --reload
Invoke-RestMethod -Method Patch http://127.0.0.1:8000/records/1 -ContentType 'application/json' -Body '{"score":1500}'
Invoke-WebRequest -Method Delete http://127.0.0.1:8000/records/1 | Select-Object StatusCode

5. 코드가 동작하는 이유

exclude_unset은 클라이언트가 보내지 않은 필드를 제외하므로 기존 값이 유지됩니다. ORM 객체 속성을 바꾸면 Session이 변경을 추적하고 commit에서 UPDATE를 실행합니다. delete도 commit해야 실제 행이 사라집니다.

6. 자주 하는 실수와 해결법

7. 직접 실습

8. 이해 점검 질문 3개

9. 핵심 요약

MINI QUIZ

CRUD(Update, Delete)와 데이터 검증 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“CRUD(Update, Delete)와 데이터 검증” 실습을 안전하게 진행하기 위한 판단으로 가장 알맞은 것은 무엇인가요?
  2. 문제 2“CRUD(Update, Delete)와 데이터 검증” 실습 중 ‘exclude_none=True만 사용합니다.’ 상황을 발견했습니다. 본문과 일치하는 설명은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

16강. CRUD(Update, Delete)와 데이터 검증 미완료 상태