FastAPI는 최신 Python 웹 프레임워크 중 하나로, 고성능과 빠른 개발 속도를 자랑하며 비동기 기능을 지원하여 효율적인 서버 애플리케이션을 만들 수 있게 해줍니다. 본 강좌에서는 FastAPI를 사용하여 데이터베이스와 연동하는 방법에 대해 자세히 설명하겠습니다. 올바른 방법으로 DB와 연결하기 위해 필요한 준비 단계와 예제 코드를 통해 실습할 수 있도록 준비했습니다.
1. FastAPI 소개
FastAPI는 Python 3.6+ 버전에서 사용할 수 있으며, 이 프레임워크는 ASGI(Asynchronous Server Gateway Interface)를 기반으로 하고 있습니다. FastAPI의 주요 장점 중 일부는 다음과 같습니다.
- 빠른 성능: FastAPI는 Starlette와 Pydantic을 기반으로 하여 높은 성능을 자랑합니다.
- 비동기 지원: 비동기 프로그래밍을 지원하여 I/O 작업을 효율적으로 처리합니다.
- 자동 문서화: OpenAPI 스펙을 사용하여 자동으로 API 문서를 생성합니다.
2. 데이터베이스와의 연결 준비
FastAPI를 통해 데이터베이스와 연결하기 위해, 다음과 같은 준비 작업이 필요합니다.
2.1. 데이터베이스 선택
일반적으로 사용하는 데이터베이스로는 MySQL, PostgreSQL, SQLite 등이 있습니다. 이 강좌에서는 SQLite를 사용하여 데이터베이스를 설정하겠습니다. SQLite는 파일 기반의 경량 데이터베이스로, 개발 및 테스트 용도로 적합합니다.
2.2. 필요한 패키지 설치
FastAPI와 데이터베이스 연결을 위해 몇 가지 패키지를 설치해야 합니다. 아래의 명령어를 사용하여 필요한 패키지를 설치합니다.
pip install fastapi uvicorn sqlalchemy databases
2.3. 데이터베이스 모델 정의
SQLAlchemy를 사용하여 데이터베이스 모델을 정의합니다. 모델은 데이터베이스의 테이블과 매핑되는 클래스입니다. 아래는 사용자 정보를 저장하기 위한 User 모델을 정의한 예제입니다.
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
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)
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
Base.metadata.create_all(bind=engine)
3. FastAPI 기본 서버 설정
FastAPI 애플리케이션을 구성하고, 데이터베이스와의 연결 설정을 진행합니다. FastAPI 인스턴스를 생성하고, 필요한 라우터를 추가하는 방법에 대해 살펴보겠습니다.
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session
app = FastAPI()
def get_db():
db = sessionmaker(bind=engine)()
try:
yield db
finally:
db.close()
@app.post("/users/")
def create_user(user: User, db: Session = Depends(get_db)):
db.add(user)
db.commit()
db.refresh(user)
return user
4. FastAPI와의 데이터베이스 상호작용
이제 FastAPI와 데이터베이스 상호작용을 위한 API 엔드포인트를 정의할 시간입니다. 사용자 생성, 조회, 조회 및 삭제와 같은 기본 CRUD 기능을 다음과 같이 구현할 수 있습니다.
@app.get("/users/{user_id}")
def read_user(user_id: int, db: Session = Depends(get_db)):
return db.query(User).filter(User.id == user_id).first()
@app.get("/users/")
def read_users(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
users = db.query(User).offset(skip).limit(limit).all()
return users
@app.delete("/users/{user_id}")
def delete_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(User).filter(User.id == user_id).first()
if user:
db.delete(user)
db.commit()
return {"message": "User deleted"}
return {"message": "User not found"}
5. 데이터베이스 연결 테스트
모든 구성이 완료되었으면 이제 FastAPI 서버를 실행하고 데이터베이스 연결이 제대로 작동하는지 테스트해보는 것이 중요합니다. 아래 명령어로 FastAPI 서버를 실행할 수 있습니다.
uvicorn main:app --reload
서버가 실행된 후, Swagger 문서를 통해 API 엔드포인트를 테스트해 볼 수 있습니다. 사용자를 생성하고, 조회하고, 삭제하는 테스트를 통해 데이터베이스 연결이 정상임을 확인할 수 있습니다.
6. FastAPI의 비동기 데이터베이스 연동
FastAPI는 비동기 기능을 제공하므로, 비동기 데이터베이스 프레임워크를 사용하여 효율적으로 데이터베이스와 상호작용할 수 있습니다. 아래는 async/await 패턴을 사용하여 비동기적으로 데이터베이스 쿼리를 수행하는 방법에 대한 간단한 예제입니다.
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from fastapi import FastAPI
DATABASE_URL = "sqlite+aiosqlite:///./test.db"
async_engine = create_async_engine(DATABASE_URL, echo=True)
Base = declarative_base()
async def get_db() -> AsyncSession:
async_session = sessionmaker(async_engine, expire_on_commit=False, class_=AsyncSession)
async with async_session() as session:
yield session
@app.post("/users/", response_model=User)
async def create_user(user: User, db: AsyncSession = Depends(get_db)):
db.add(user)
await db.commit()
await db.refresh(user)
return user
비동기 데이터베이스 연동을 통해 성능을 더욱 최적화할 수 있습니다. 이러한 방법을 통해 더 많은 클라이언트 요청을 처리하면서 서버 자원을 효율적으로 사용할 수 있습니다.
7. 결론
FastAPI와 데이터베이스를 함께 사용하는 방법을 살펴보았습니다. FastAPI 서버를 설정하고, 데이터베이스와의 연결을 위한 준비 과정을 통해 기본적인 CRUD 기능을 구현했습니다. 이 과정에서 FastAPI의 비동기 처리 기능을 활용했다면 더욱 효과적인 웹 애플리케이션을 구축할 수 있습니다.
이제 여러분들은 FastAPI와 데이터베이스를 연동한 시스템을 구축하는 기초적인 방법을 배우셨습니다. 이 지식을 바탕으로 더 복잡한 애플리케이션을 설계하고 개발해보세요.