FastAPI 서버개발, SQLAlchemy의 DB 모델 정의

FastAPI는 Python으로 웹 애플리케이션을 개발하기 위해 설계된 모던 웹 프레임워크로, 매우 빠르며 비동기 프로그래밍을 지원합니다. 이번 포스트에서는 FastAPI의 백엔드 개발 환경에서 SQLAlchemy를 사용하여 데이터베이스 모델을 정의하는 방법에 대해 자세히 설명하겠습니다. SQLAlchemy는 Python의 ORM(Object Relational Mapping) 라이브러리로, 데이터베이스와의 상호작용을 더 간편하게 만들어줍니다.

1. FastAPI와 SQLAlchemy 소개

FastAPI는 다음과 같은 몇 가지 주요 이점을 가지고 있습니다:

  • 비동기 지원: Python의 asyncawait 구문을 사용하여 비동기 프로그래밍을 간편하게 구현할 수 있습니다.
  • 자동화된 문서화: FastAPI는 OpenAPI 스펙을 기반으로 클라이언트를 위한 API 문서를 자동으로 생성합니다.
  • 고성능: Starlette 위에 구축되어 있어 높은 성능을 자랑합니다.

SQLAlchemy는 관계형 데이터베이스와 상호작용하기 위한 ORM으로 다음과 같은 이점이 있습니다:

  • 데이터베이스 독립성: 여러 종류의 데이터베이스와 호환됩니다.
  • 복잡한 쿼리를 쉽게 작성: SQLAlchemy의 쿼리 빌더를 사용하면 복잡한 SQL 쿼리를 쉽게 작성할 수 있습니다.
  • 모델 정의: Python 클래스 정의를 통해 데이터베이스 모델을 직관적으로 생성할 수 있습니다.

2. 개발 환경 설정

FastAPI와 SQLAlchemy를 사용하기 위해서는 우선 Python이 설치되어 있어야 합니다. 각 패키지를 설치하는 과정은 다음과 같습니다.

pip install fastapi[all] sqlalchemy

참고: 위의 명령어에서 fastapi[all]는 FastAPI와 함께 uvicorn과 같은 모든 의존성을 설치합니다.

3. SQLAlchemy DB 모델 정의하기

SQLAlchemy를 사용하여 데이터베이스 모델을 정의하려면 몇 가지 단계를 거쳐야 합니다:

  1. SQLAlchemy 엔진 생성
  2. 세션 클래스 정의
  3. 데이터베이스 모델 정의
  4. 테이블 생성

3.1 SQLAlchemy 엔진 생성

데이터베이스 연결을 위해 SQLAlchemy 엔진을 생성해야 합니다. 이는 데이터베이스 URL을 통해 이루어집니다. 예를 들어, SQLite 데이터베이스를 사용할 경우 아래와 같이 설정할 수 있습니다.

from sqlalchemy import create_engine

DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})

3.2 세션 클래스 정의

SQLAlchemy의 세션은 데이터베이스에 대한 트랜잭션을 관리합니다. 아래 코드를 통해 세션 클래스를 정의할 수 있습니다.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

3.3 데이터베이스 모델 정의

이제 SQLAlchemy의 Base 클래스를 상속받아 원하는 데이터베이스 모델을 정의할 수 있습니다. 예를 들어, 사용자 정보를 저장하기 위한 User 모델은 다음과 같이 정의할 수 있습니다.

from sqlalchemy import Column, Integer, String, Boolean

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String, unique=True, index=True)
    email = Column(String, unique=True, index=True)
    is_active = Column(Boolean, default=True)

3.4 테이블 생성하기

모델 정의가 끝났다면 실제 데이터베이스에 테이블을 생성해야 합니다. 다음과 같은 코드를 사용하여 테이블을 생성할 수 있습니다:

Base.metadata.create_all(bind=engine)

4. FastAPI와 SQLAlchemy 통합하기

이제 FastAPI를 사용해 만든 API와 SQLAlchemy 데이터베이스 모델을 통합할 차례입니다. 이를 위해 FastAPI 경로에서 CRUD(Create, Read, Update, Delete) 작업을 처리하는 엔드포인트를 작성합니다.

4.1 FastAPI 애플리케이션 생성

from fastapi import FastAPI

app = FastAPI()

4.2 CRUD API 엔드포인트 작성

다음으로, CRUD 작업을 위한 엔드포인트를 정의합니다.

4.2.1 Create: 사용자 생성

from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session

# 의존성 주입을 위한 함수
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/users/", response_model=User)
def create_user(user: User, db: Session = Depends(get_db)):
    db.add(user)
    db.commit()
    db.refresh(user)
    return user

4.2.2 Read: 사용자 조회

@app.get("/users/{user_id}", response_model=User)
def read_user(user_id: int, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

4.2.3 Update: 사용자 업데이트

@app.put("/users/{user_id}", response_model=User)
def update_user(user_id: int, user: User, db: Session = Depends(get_db)):
    db_user = db.query(User).filter(User.id == user_id).first()
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    
    db_user.username = user.username
    db_user.email = user.email
    db.commit()
    db.refresh(db_user)
    return db_user

4.2.4 Delete: 사용자 삭제

@app.delete("/users/{user_id}")
def delete_user(user_id: int, db: Session = Depends(get_db)):
    db_user = db.query(User).filter(User.id == user_id).first()
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    db.delete(db_user)
    db.commit()
    return {"detail": "User deleted"}

5. 결론

이 글에서 우리는 FastAPI와 SQLAlchemy를 사용하여 데이터베이스 모델을 정의하고, 이를 기반으로 CRUD API를 구축하는 방법에 대해 알아보았습니다. FastAPI의 비동기 지원과 SQLAlchemy의 ORM 기능을 결합하면 Python으로 웹 애플리케이션을 효율적으로 개발할 수 있습니다. 이 과정을 통해 더 나은 백엔드 시스템을 구축하고, 확장 가능한 API를 만들 수 있습니다.

추가적으로 FastAPI의 기능을 이용하여 데이터 유효성 검증, 쿼리 파라미터 처리, JWT 인증, CORS 설정 등 다양한 기능을 적용할 수 있습니다. 이러한 기능들은 실제 실무에서 매우 유용하게 사용될 수 있습니다.

FastAPI와 SQLAlchemy의 기본 사용법을 익힌 후에는 복잡한 비즈니스 로직을 추가하여 더욱 정교한 애플리케이션을 만들어 가는 과정을 통해 더 큰 발전을 이룰 수 있을 것입니다.