""" 데이터베이스 설정 및 연결 """ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker from sqlalchemy.orm import DeclarativeBase, sessionmaker, Session from sqlalchemy import MetaData, create_engine from typing import AsyncGenerator, Generator from .config import settings # SQLAlchemy 메타데이터 설정 metadata = MetaData( naming_convention={ "ix": "ix_%(column_0_label)s", "uq": "uq_%(table_name)s_%(column_0_name)s", "ck": "ck_%(table_name)s_%(constraint_name)s", "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", "pk": "pk_%(table_name)s" } ) class Base(DeclarativeBase): """SQLAlchemy Base 클래스""" metadata = metadata # 비동기 데이터베이스 엔진 생성 engine = create_async_engine( settings.DATABASE_URL, echo=settings.DEBUG, future=True, pool_pre_ping=True, pool_recycle=300, ) # 동기 데이터베이스 엔진 생성 (노트 API용) sync_database_url = settings.DATABASE_URL.replace("postgresql+asyncpg://", "postgresql://") sync_engine = create_engine( sync_database_url, echo=settings.DEBUG, pool_pre_ping=True, pool_recycle=300, ) # 비동기 세션 팩토리 AsyncSessionLocal = async_sessionmaker( engine, class_=AsyncSession, expire_on_commit=False, ) # 동기 세션 팩토리 SyncSessionLocal = sessionmaker( sync_engine, class_=Session, expire_on_commit=False, ) async def get_db() -> AsyncGenerator[AsyncSession, None]: """비동기 데이터베이스 세션 의존성""" async with AsyncSessionLocal() as session: try: yield session except Exception: await session.rollback() raise finally: await session.close() def get_sync_db() -> Generator[Session, None, None]: """동기 데이터베이스 세션 의존성 (노트 API용)""" session = SyncSessionLocal() try: yield session except Exception: session.rollback() raise finally: session.close() async def init_db() -> None: """데이터베이스 초기화""" from ..models import user, document, highlight, note, bookmark async with engine.begin() as conn: # 모든 테이블 생성 await conn.run_sync(Base.metadata.create_all) # 관리자 계정 생성 await create_admin_user() async def create_admin_user() -> None: """관리자 계정 생성 (존재하지 않을 경우)""" from ..models.user import User from .security import get_password_hash from sqlalchemy import select async with AsyncSessionLocal() as session: # 관리자 계정 존재 확인 result = await session.execute( select(User).where(User.email == settings.ADMIN_EMAIL) ) admin_user = result.scalar_one_or_none() if not admin_user: # 관리자 계정 생성 admin_user = User( email=settings.ADMIN_EMAIL, hashed_password=get_password_hash(settings.ADMIN_PASSWORD), is_active=True, is_admin=True, full_name="Administrator" ) session.add(admin_user) await session.commit() print(f"관리자 계정이 생성되었습니다: {settings.ADMIN_EMAIL}")