본문 바로가기

Python

FastAPI에서 MongoDB 연결하기

FastAPI와 MongoDB

몽고DB에는 Pymongo와 Motor 두가지 파이썬 드라이버가 있다.Fastapi는 이 두 드라이버중 Motor 하나만 사용할 수 있는데, FastAPI는 ASGI와 비동기를 기반으로 구축되었기 때문에 asyncio와 호환되는 Motor를 사용해야 한다. PyMongo는 동기식 애플리케이션에 사용된다.

Motor 설치

pip install motor[srv]
  • srv 엑스트라는 MongoDB Atlas 연결 문자열과, 연결하는 데 필요한 몇 가지 추가 종속성이 포함되어 있다

MongoDB 연결

motor.motor_asyncio 패키지에서 AsyncIOMotorClient 모듈을 가져와야 한다.

from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient

app = FastAPI()

MONGO_URL = "mongodb+srv://myDatabaseUser:D1fficultP%40ssw0rd@mongodb0.example.com/?authSource=admin&replicaSet=myRepl"
client = AsyncIOMotorClient(MONGO_URL)
  • mongodb + srv는 DNS SRV 레코드를 사용하는 MongoDB 클러스터에 연결하는 새로운 방법이다. 기본적으로 MongoDB는 mongodb+srv를 사용할 것을 권장한다.
  • 주의사항: mongodb+srv 프로토콜은 DNS를 사용하여 MongoClient가 연결을 시도할 시드 목록을 확인하므로 DNS 쿼리가 실패하면 클라이언트 생성이 실패한다.

MONGO_URL을 코드에 저장하는 것보다 환경변수로 관리하는 것이 좋다.

from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient

app = FastAPI()

# 환경변수 MONGODB_URI에서 MongoDB 연결 문자열을 가져온다
CONNECTION_STRING = os.environ['MONGODB_URI'] # 또는 env에서 가져와도 된다.

# MongoDB 연결 클라이언트 생성
client = AsyncIOMotorClient(CONNECTION_STRING)
  • 코드에 연결문자열 처럼 비밀을 유지 해야하는 부분을 저장하는 건 좋지 않다.
  • .env, .envrc 처럼 별도의 비밀 파일로 관리는 것이 좋다.

기본적으로 이렇게 하면 MongoDB와 연결된다. 하지만 애플리케이션의 최상위 수준에서 데이터베이스 연결을 초기화 하는 것 보다 애플리케이션의 시작 및 종료 이벤트에 응답하여 클라이언트 연결을 정상적으로 초기화하고 종료 하는 것이 더 좋다.

MongoDB 초기화

클라이언트를 FastAPI의 앱 객체에 연결하여 코드베이스의 모든 위치에서 경로 작업 기능을 사용할 수 있도록 해야한다. 보통 이를 엔드포인트라고 부른다.

전역 변수에 의존하는 경우 필요한 모든 곳에서 변수를 가져와야 하므로 지저분해 질 수 있다.

from contextlib import asynccontextmanager
from logging import info @asynccontextmanager
async def db_lifespan(app: FastAPI):
    # app 객체에 MongoDB 클라이언트 연결
    app.mongodb_client = AsyncIOMotorClient(CONNECTION_STRING)
    app.database = app.mongodb_client.get_default_database()
    ping_response = await app.database.command("ping")
    if int(ping_response["ok"]) != 1:
        raise Exception("Problem connecting to database cluster.")
    else:
        info("Connected to database cluster.")

    # 앱 객체를 다시 양보하여 이후 프로세스가 진행될 수 있도록 한다
    yield

    # 앱이 종료되면 MongoDB도 닫는다.
    app.mongodb_client.close()

# FastAPI lifespan이벤트에 MongoDB 커넥션을 등록한다. 
app: FastAPI = FastAPI(lifespan=db_lifespan)
  • lifespan이벤트는 애플리케이션이 요청을 받기 시작하기 전과 요청 처리를 마친 직후에 실행 된다.
  • 전체 앱에 사용해야 하는 리소스, 요청 간에 공유 되는 리소스, 나중에 정리 해야 하는 리소스를 설정하는 데 유용하다.(예를 들어 데이터베이스 연결)

'Python' 카테고리의 다른 글

[FastAPI] PUT과 PATCH 처리  (0) 2024.08.01
Django의 DB모델링  (0) 2023.07.02