2026년 7월 21일 화요일

database.py



import os
from contextlib import contextmanager # contextmanager 임포트
from typing import Generator

from dotenv import load_dotenv

from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base, Session # Session 타입 힌트 추가

load_dotenv()

# 환경 변수 로딩 시 변수명 축약 대신 명시적인 이름 사용 권장
MYSQL_USER = os.environ.get("MYSQL_USER")
MYSQL_PASSWORD = os.environ.get("MYSQL_PASSWORD")
MYSQL_HOST = os.environ.get("MYSQL_ALEMBIC_HOST") # alembic 전용 호스트가 아니라면 MYSQL_HOST로 통일 가능
MYSQL_PORT = os.environ.get("MYSQL_ALEMBIC_PORT")
MYSQL_DB = os.environ.get("MYSQL_DATABASE")

# MySQL 연결 설정 (사용자, 비밀번호, 호스트, DB이름 수정)
# 예: mysql+aiomysql://user:password@localhost:3306/dbname
SQLALCHEMY_DATABASE_URL = f"mysql+aiomysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DB}"
# SQLite 사용 시: SQLALCHEMY_DATABASE_URL = "sqlite:///./myapi.db"

# create_engine 설정: MySQL 연결 시 pool_pre_ping은 좋은 관례입니다.
engine = create_async_engine(
    SQLALCHEMY_DATABASE_URL, 
    echo=True,
    pool_pre_ping=True,  # 연결 유효성 체크 (MySQL 연결 끊김 방지)
    pool_recycle=3600,   # 연결 재사용 시간 설정    
    # SQLite 사용 시: connect_args={"check_same_thread": False}
)

# 세션 생성을 위한 팩토리
async_session = async_sessionmaker(
    bind=engine, 
    class_=AsyncSession, 
    expire_on_commit=False
)


# Base 모델 클래스 생성
Base = declarative_base()

# 참고: Alembic 사용 시 필요한 주석들은 제거하거나 별도의 alembic config 파일로 옮기는 것이 깔끔합니다.


database.py

import os from contextlib import contextmanager # contextmanager 임포트 from typing import Generator from dotenv...