본문으로 건너뛰기
백엔드 기초집: 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)와 데이터 검증 미완료 상태