C.W.K.
Stream
Lesson 04 of 10 · published

FastAPI 의 Connection Lifecycle

~14 min · fastapi, lifespan, aiosqlite

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

한 번 열고 한 번 닫음

FastAPI 가 startup + shutdown 에 도는 lifespan context manager 줌. Idiomatic 패턴: 거기서 DB connection open + app.state 에 stash, 그 다음 dependency injection 으로 route 에 노출.

두 함정 회피:

  • Request 마다 새 connection — 파일 핸들 낭비 + in-memory 캐싱 막음.
  • Module import 시점에 open — event loop 존재 전; aiosqlite 가 loop 필요.
Self-reference: 피파 backend/main.py 가 정확히 이 lifespan 패턴: startup 에 SQLite store 한 번 open, migration 실행, app.state.store 에 attach, shutdown 에 깨끗 close. Route 가 Depends 로 store pull.

Code

FastAPI + aiosqlite lifespan·python
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends, Request
import aiosqlite

@asynccontextmanager
async def lifespan(app: FastAPI):
    conn = await aiosqlite.connect('myapp.db')
    conn.row_factory = aiosqlite.Row
    await conn.execute('PRAGMA journal_mode = WAL')
    await conn.execute('PRAGMA foreign_keys = ON')
    await conn.execute('PRAGMA busy_timeout = 5000')
    app.state.db = conn
    try:
        yield
    finally:
        await conn.close()

app = FastAPI(lifespan=lifespan)

async def db(request: Request) -> aiosqlite.Connection:
    return request.app.state.db

@app.get('/notes')
async def list_notes(conn: aiosqlite.Connection = Depends(db)):
    async with conn.execute('SELECT id, body FROM notes ORDER BY id DESC LIMIT 50') as cur:
        return [dict(row) async for row in cur]

External links

Exercise

Lifespan 패턴 사용해서 aiosqlite 백엔드 endpoint 한 개 짜리 tiny FastAPI 빌드. uvicorn 으로 돌리고 hey/ab 로 동시 1000 request hit. Latency sub-ms 유지 + 'database is locked' 에러 없음 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.