한양과학기술고등학교

에듀테크 프로젝트 대시보드

yield 의존성 — 리소스 정리

yield DB 세션 정리 cleanup 전역 의존성

return 대신 yield 를 쓰면, 응답이 끝난 뒤 yield 이후 코드가 실행됩니다. DB 세션·파일·락 정리에 씁니다.

1. DB 세션 의존성 (동기)

from sqlalchemy.orm import Session
from app.database import SessionLocal

def get_db():
    db = SessionLocal()
    try:
        yield db          # 여기서 라우트 실행
    finally:
        db.close()        # 응답 후 항상 정리

DbDep = Annotated[Session, Depends(get_db)]

@app.get("/items")
def list_items(db: DbDep):
    return db.query(Item).all()

2. 예외 처리와 롤백

def get_db():
    db = SessionLocal()
    try:
        yield db
        db.commit()          # 라우트가 정상 종료하면 커밋
    except Exception:
        db.rollback()        # 예외 시 롤백
        raise
    finally:
        db.close()
주의
  • yield 이후 코드에서 HTTPException 을 새로 던져도 클라이언트 응답은 이미 나갔을 수 있음
  • 정리 코드는 예외를 삼키지 말고 로깅만 하거나 다시 raise

3. 비동기 버전

from app.database import AsyncSessionLocal

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

AsyncDbDep = Annotated[AsyncSession, Depends(get_db)]

4. 전역 의존성

app = FastAPI(dependencies=[Depends(verify_api_key), Depends(rate_limit)])
# 모든 경로에 적용. 라우터 단위는 include_router(..., dependencies=[...])

5. lru_cache 로 싱글턴 의존성

from functools import lru_cache

@lru_cache
def get_settings() -> Settings:
    return Settings()      # .env 를 한 번만 읽음

SettingsDep = Annotated[Settings, Depends(get_settings)]
"타입 힌트 하나로 검증·직렬화·문서화가 동시에 이뤄진다"