FastAPI 5일차 - SQLAlchemy CRUD 완성 및 Python 비동기 (Async) 프로그래밍

빛나김·2026년 1월 15일

Fast API

목록 보기
5/7
post-thumbnail

안녕하세요! 오늘은 FastAPI 학습 5일차입니다.
지난 시간까지 메모리상의 리스트(items = [])를 가지고 놀았다면, 오늘은 진짜 데이터베이스를 연동해서 영구적으로 데이터를 저장하는 방법(SQLAlchemy)과, FastAPI의 킬러 기능인 비동기 프로그래밍(Async)에 대해 알아보겠습니다.


📑 오늘의 목표

  1. CRUD 완성하기: PUTDELETE까지 구현해서 완벽한 REST API를 만듭니다.
  2. SQLAlchemy 연동: 파이썬 코드로 DB를 조작하는 ORM을 사용해 실제 DB에 데이터를 저장합니다.
  3. 비동기 프로그래밍 입문: async, await가 도대체 뭔지, 왜 빠른지 직접 눈으로 확인합니다.

1️⃣ CRUD의 완성: Update(PUT)와 Delete

🐢 PUT vs PATCH: 수정이라고 다 같은 수정이 아니다?

우리는 지난 시간에 PATCH를 배웠죠. 그런데 PUT도 수정을 의미합니다. 차이가 뭘까요?

메소드의미비유특징
PUT전체 대체 (Replace)"이 상자, 새 상자로 통째로 바꿔주세요."모든 필드 정보를 다 줘야 함 (필수)
PATCH부분 수정 (Update)"상자 이름만 유성매직으로 고쳐주세요."바꾸고 싶은 필드만 주면 됨 (선택)

코드 예시 (PUT):

@app.put("/items/{item_id}", response_model=ItemResponse)
def replace_item(item_id: int, item_request: ItemReplaceUpdateRequest, db: Session = Depends(get_db)):
    # ... (조회 로직) ...
    
    # 묻지도 따지지도 않고 덮어씌우기
    item.name = item_request.name 
    item.price = item_request.price
    
    db.add(item)
    db.commit()
    db.refresh(item)
    return item




2️⃣ SQLAlchemy로 진짜 DB 연동하기

이제 fake_db = {} 따위는 버립니다. SQLAlchemy ORM을 사용하면 SQL 쿼리문(SELECT * FROM...)을 몰라도 파이썬 클래스처럼 데이터를 다룰 수 있습니다.

핵심 3대장 메소드

  1. db.add(item): "이거 DB에 내보낼 준비 해!" (장바구니 담기)
  2. db.commit(): "진짜 저장해!" (결제 완료 - DB 반영)
  3. db.refresh(item): "방금 저장된 거 DB에서 다시 가져와!" (새로고침 - ID 등 자동생성 값 확인)

실전 코드: Create (생성)

@app.post("/items", status_code=201)
def create_item(item_request: ItemCreateRequest, db: Session = Depends(get_db)):
    # 1. ORM 객체 만들기
    new_item = Item(name=item_request.name, price=item_request.price)
    
    # 2. 세션에 추가하고 커밋
    db.add(new_item)
    db.commit()
    
    # 3. 최신 정보 로드 (ID가 생성됨)
    db.refresh(new_item)
    
    return new_item

실전 코드: Delete (삭제)

삭제는 더 쉽습니다. delete 하고 commit 하면 끝!

@app.delete("/items/{item_id}", status_code=204)
def delete_item(item_id: int, db: Session = Depends(get_db)):
    # 1. 삭제할 놈 찾기
    statement = select(Item).where(Item.id == item_id)
    item = db.execute(statement).scalars().first()
    
    if item is None:
        raise HTTPException(status_code=404, detail="Item not found")

    # 2. 삭제하고 커밋
    db.delete(item)
    db.commit()
    
    return # 204는 내용이 없으므로 빈 리턴


3️⃣ Python 비동기(Async) 프로그래밍: 왜 FastAPI인가?

FastAPI가 "Fast"한 이유는 바로 이 비동기 처리 덕분입니다.

동기(Sync) vs 비동기(Async)

  • 동기 (Sync): 라면 물 끓을 때까지 냄비 앞에서 아무것도 안 하고 멍하니 기다림. (비효율 끝판왕)
  • 비동기 (Async): 물 올려놓고(await), 끓는 동안 파 썰고 김치 꺼냄. (멀티태스킹 고수)

웹 서비스에서는 DB 조회, 외부 API 호출 같은 "기다리는 시간(I/O Bound)"이 아주 많습니다. 비동기는 이 시간을 알뜰하게 씁니다.

핵심 키워드 정리

  • async def: "이 함수는 비동기 함수(코루틴)야!"라고 선언.
  • await: "이 작업 끝날 때까지 잠깐 제어권 넘길게(다른 일 하고 있어)."
  • asyncio.gather(): 여러 비동기 작업을 한 번에 실행.

백문이 불여일코드: 속도 차이 체험

가짜 잠자기(sleep) 실험

  • 상황: 2초 걸리는 작업 2개를 수행한다.

1. 동기 방식 (Sync)

import time

def sync_task():
    time.sleep(2) # 2초 멈춤

# 실행
sync_task() # 2초
sync_task() # 2초
# 총 4초 걸림 🐢

2. 비동기 방식 (Async)

import asyncio

async def async_task():
    await asyncio.sleep(2) # 2초 기다릴 동안 다른 일 함

async def main():
    # 두 작업을 동시에 던짐!
    await asyncio.gather(async_task(), async_task())

# 실행
asyncio.run(main()) 
# 총 2초 걸림 (...) 🐇

결과: 비동기 처리를 하면 I/O 대기 시간이 겹쳐져서 전체 실행 시간이 획기적으로 줄어듭니다!


✅ 5일차 요약

오늘 우리는 SQLAlchemy를 통해 코드를 데이터베이스와 연결하는 강력한 기술을 익혔고, 비동기 프로그래밍을 통해 서버의 성능을 극한으로 끌어올릴 준비를 마쳤습니다.

  • PUT vs PATCH 구분하기
  • db.add, db.commit, db.refresh 삼박자 이해하기
  • db.delete로 데이터 삭제하기
  • asyncawait로 효율적인 비동기 코드 작성하기

다음 시간에는 이 비동기 기술을 데이터베이스에도 적용하는 방법과 기능 고도화를 진행해보겠습니다. 오늘도 고생 많으셨습니다! 👋

profile
함께 성장

0개의 댓글