- Published on
FastAPI 데이터베이스 연동: SQLAlchemy로 DB 마스터하기 🎯
- Authors
- Name
- devnmin
FastAPI + SQLAlchemy: 데이터베이스 연동 완벽 가이드 🚀
안녕하세요, FastAPI 마스터가 되는 여정의 두 번째 이야기입니다! 오늘은 데이터베이스 연동에 대해 알아볼 건데요, 걱정 마세요. 제가 쉽고 재미있게 설명해드릴게요! 😊
1. 시작하기 전에... 🤔
먼저 필요한 패키지들을 설치해볼까요? (저랑 같이 터미널을 켜주세요! 👨💻)
pip install sqlalchemy alembic psycopg2-binary
# psycopg2는 PostgreSQL을 쓸 거라서 설치해요!
# MySQL 派들은 mysql-connector-python을 설치하시면 됩니다 😉
2. 데이터베이스 설정하기 ⚙️
# database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# 여기서 잠깐! 🤚
# 실제 프로젝트에서는 이런 민감한 정보는 환경변수로 관리해야 해요!
DATABASE_URL = "postgresql://user:password@localhost/dbname"
# 엔진 만들기 (부릉부릉! 🚗)
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
# 의존성 주입을 위한 함수
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close() # 꼭 닫아주세요! 안 그러면 DB가 슬퍼합니다 😢
3. 모델 정의하기 🏗️
# models.py
from sqlalchemy import Column, Integer, String, Boolean, DateTime
from sqlalchemy.sql import func
from database import Base
class User(Base):
__tablename__ = "users" # 테이블 이름은 복수형으로 짓는 게 관례예요!
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True) # 중복 이메일은 NO! 🚫
username = Column(String, unique=True)
password = Column(String) # 해시된 비밀번호를 저장할 거예요
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, server_default=func.now()) # 가입 시간도 기록해요!
4. Pydantic 스키마 정의하기 📝
# schemas.py
from pydantic import BaseModel, EmailStr
from datetime import datetime
from typing import Optional
class UserBase(BaseModel):
email: EmailStr
username: str
class UserCreate(UserBase):
password: str # 비밀번호는 생성할 때만 받아요!
class User(UserBase):
id: int
is_active: bool
created_at: datetime
class Config:
from_attributes = True # SQLAlchemy 모델 -> Pydantic 모델 변환 지원
5. CRUD 연산 구현하기 🛠️
# crud.py
from sqlalchemy.orm import Session
from . import models, schemas
from fastapi import HTTPException
def create_user(db: Session, user: schemas.UserCreate):
# 이메일이 이미 있는지 체크! (중복 가입 방지 🚨)
if get_user_by_email(db, user.email):
raise HTTPException(status_code=400, detail="이메일이 이미 등록되어 있어요!")
# 비밀번호는 해시해서 저장해야 해요! (보안 중요해요 🔒)
hashed_password = get_password_hash(user.password)
db_user = models.User(
email=user.email,
username=user.username,
password=hashed_password
)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
6. API 엔드포인트 만들기 🎯
# main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import get_db, engine
models.Base.metadata.create_all(bind=engine) # 테이블 생성!
app = FastAPI()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
7. 데이터베이스 마이그레이션 관리하기 🔄
Alembic으로 마이그레이션을 관리해봅시다! (버전 관리처럼 생각하시면 돼요 😉)
# 초기화
alembic init alembic
# 마이그레이션 파일 생성
alembic revision --autogenerate -m "Create users table"
# 마이그레이션 실행
alembic upgrade head
실전 팁! 💡
- 커넥션 풀 설정하기
engine = create_engine(
DATABASE_URL,
pool_size=5, # 동시 연결 수
max_overflow=10, # 추가로 허용할 연결 수
pool_timeout=30 # 타임아웃 시간
)
- 비동기 지원 추가하기
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
# PostgreSQL 비동기 드라이버 필요해요!
# pip install asyncpg
- 데이터베이스 인덱스 활용하기
# 자주 검색하는 필드에는 인덱스를 추가해주세요!
email = Column(String, unique=True, index=True)
자주 하는 실수들 🚨
세션 관리를 제대로 안 하는 경우
with
문이나 의존성 주입으로 꼭 관리해주세요!
비밀번호를 평문으로 저장하는 경우
- 절대 금지! 꼭 해시해서 저장하세요!
N+1 쿼리 문제
joinedload
나selectinload
사용하세요!
마무리 🎉
이제 여러분은 FastAPI에서 데이터베이스를 다룰 수 있는 마스터가 되었습니다! 👏 더 자세한 내용은 FastAPI 공식 문서를 참고해주세요.
다음 시간에는... FastAPI로 인증/인가 시스템 구현하는 방법을 알아볼 거예요! 기대해주세요! 😉