Spaces:
Sleeping
Sleeping
| """ | |
| SmartEyeSsen Backend - Database Connection Configuration | |
| ========================================================= | |
| SQLAlchemy ์์ง, ์ธ์ ๊ด๋ฆฌ ๋ฐ Base ํด๋์ค ์ ์ | |
| ์ฃผ์ ๊ธฐ๋ฅ: | |
| - MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ค์ | |
| - ์ธ์ ์์ฑ ๋ฐ ์์กด์ฑ ์ฃผ์ | |
| - ๋น๋๊ธฐ ์ปจํ ์คํธ ๋งค๋์ ์ง์ | |
| """ | |
| from sqlalchemy import create_engine, event, text | |
| from sqlalchemy.ext.declarative import declarative_base | |
| from sqlalchemy.orm import sessionmaker, Session | |
| from typing import Generator | |
| import os | |
| from dotenv import load_dotenv | |
| # ============================================================================ | |
| # ํ๊ฒฝ ๋ณ์ ๋ก๋ | |
| # ============================================================================ | |
| from pathlib import Path | |
| # .env ํ์ผ ๊ฒฝ๋ก ๋ช ์์ ์ผ๋ก ์ง์ | |
| env_path = Path(__file__).parent.parent / '.env' | |
| load_dotenv(dotenv_path=env_path, override=True) | |
| # ============================================================================ | |
| # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ | |
| # ============================================================================ | |
| DB_HOST = os.getenv("DB_HOST", "localhost") | |
| DB_PORT = os.getenv("DB_PORT", "3306") | |
| DB_USER = os.getenv("DB_USER", "root") | |
| DB_PASSWORD = os.getenv("DB_PASSWORD", "root") # โ ๊ธฐ๋ณธ๊ฐ์ "root"๋ก ๋ณ๊ฒฝ | |
| DB_NAME = os.getenv("DB_NAME", "smarteyessen_db") | |
| # ๋๋ฒ๊ทธ ์ถ๋ ฅ (๊ฐ๋ฐ ์ค์๋ง ์ฌ์ฉ) | |
| print(f"๐ DB Config: {DB_USER}@{DB_HOST}:{DB_PORT}/{DB_NAME}") | |
| print(f"๐ Password loaded: {'Yes' if DB_PASSWORD else 'No'}") | |
| # MySQL ์ฐ๊ฒฐ URL ์์ฑ | |
| # pymysql ๋๋ผ์ด๋ฒ ์ฌ์ฉ, charset=utf8mb4 ์ค์ | |
| SQLALCHEMY_DATABASE_URL = ( | |
| f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}" | |
| f"?charset=utf8mb4&use_unicode=1" | |
| ) | |
| # ============================================================================ | |
| # SQLAlchemy Engine ์์ฑ | |
| # ============================================================================ | |
| engine = create_engine( | |
| SQLALCHEMY_DATABASE_URL, | |
| # ์ฐ๊ฒฐ ํ ์ค์ | |
| pool_size=10, # ๊ธฐ๋ณธ ์ฐ๊ฒฐ ์ | |
| max_overflow=20, # ์ถ๊ฐ ๊ฐ๋ฅํ ์ต๋ ์ฐ๊ฒฐ ์ | |
| pool_pre_ping=True, # ์ฐ๊ฒฐ ์ ํจ์ฑ ์๋ ์ฒดํฌ | |
| pool_recycle=3600, # 1์๊ฐ๋ง๋ค ์ฐ๊ฒฐ ์ฌ์์ฑ | |
| echo=False, # SQL ๋ก๊ทธ ์ถ๋ ฅ (๊ฐ๋ฐ ์ True๋ก ๋ณ๊ฒฝ ๊ฐ๋ฅ) | |
| # PyMySQL ๋๋ผ์ด๋ฒ์ ์ง์ charset ์ ๋ฌ (ํ๊ธ ์ธ์ฝ๋ฉ ๋ฌธ์ ํด๊ฒฐ) | |
| connect_args={ | |
| "charset": "utf8mb4", | |
| "use_unicode": True, | |
| "init_command": "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci" | |
| } | |
| ) | |
| # ============================================================================ | |
| # SessionLocal ํด๋์ค ์์ฑ | |
| # ============================================================================ | |
| SessionLocal = sessionmaker( | |
| autocommit=False, # ์๋ ์ปค๋ฐ ๋นํ์ฑํ | |
| autoflush=False, # ์๋ ํ๋ฌ์ ๋นํ์ฑํ | |
| bind=engine, | |
| ) | |
| # ============================================================================ | |
| # Base ํด๋์ค ์ ์ | |
| # ============================================================================ | |
| Base = declarative_base() | |
| # ============================================================================ | |
| # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ์ ์์กด์ฑ ํจ์ | |
| # ============================================================================ | |
| def get_db() -> Generator[Session, None, None]: | |
| """ | |
| FastAPI ์์กด์ฑ ์ฃผ์ ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ์ ์์ฑ | |
| ์ฌ์ฉ ์์: | |
| ```python | |
| @app.get("/users") | |
| def read_users(db: Session = Depends(get_db)): | |
| users = db.query(User).all() | |
| return users | |
| ``` | |
| Yields: | |
| Session: SQLAlchemy ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ์ | |
| """ | |
| db = SessionLocal() | |
| try: | |
| yield db | |
| finally: | |
| db.close() | |
| # ============================================================================ | |
| # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๊ธฐํ ํจ์ | |
| # ============================================================================ | |
| def init_db(): | |
| """ | |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ ์์ฑ (๊ฐ๋ฐ ํ๊ฒฝ์ฉ) | |
| ์ฃผ์: ์ด์ ํ๊ฒฝ์์๋ Alembic ๋ง์ด๊ทธ๋ ์ด์ ์ฌ์ฉ ๊ถ์ฅ | |
| """ | |
| # models.py importํ์ฌ ํ ์ด๋ธ ์ ์ ๋ก๋ | |
| from . import models # ๋ชจ๋ ๋ชจ๋ธ ํด๋์ค๋ฅผ Base.metadata์ ๋ฑ๋ก | |
| # models.py์์ ์ ์ํ ๋ชจ๋ ํ ์ด๋ธ ์์ฑ | |
| Base.metadata.create_all(bind=engine) | |
| print("โ Database tables created successfully!") | |
| def drop_all_tables(): | |
| """ | |
| ๋ชจ๋ ํ ์ด๋ธ ์ญ์ (๊ฐ๋ฐ/ํ ์คํธ ํ๊ฒฝ์ฉ) | |
| โ ๏ธ ์ฃผ์: ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ญ์ ๋ฉ๋๋ค! | |
| """ | |
| # models.py importํ์ฌ ํ ์ด๋ธ ์ ์ ๋ก๋ | |
| from . import models # ๋ชจ๋ ๋ชจ๋ธ ํด๋์ค๋ฅผ Base.metadata์ ๋ฑ๋ก | |
| Base.metadata.drop_all(bind=engine) | |
| print("โ ๏ธ All database tables dropped!") | |
| # ============================================================================ | |
| # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ ์คํธ ํจ์ | |
| # ============================================================================ | |
| def test_connection(): | |
| """ | |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ ์คํธ | |
| Returns: | |
| bool: ์ฐ๊ฒฐ ์ฑ๊ณต ์ฌ๋ถ | |
| """ | |
| try: | |
| # ๊ฐ๋จํ ์ฟผ๋ฆฌ ์คํํ์ฌ ์ฐ๊ฒฐ ํ์ธ | |
| with engine.connect() as connection: | |
| result = connection.execute(text("SELECT 1")) | |
| print("โ Database connection successful!") | |
| return True | |
| except Exception as e: | |
| print(f"โ Database connection failed: {e}") | |
| return False | |
| # ============================================================================ | |
| # SQLAlchemy Event Listeners (์ ํ์ฌํญ) | |
| # ============================================================================ | |
| def set_sqlite_pragma(dbapi_conn, connection_record): | |
| """ | |
| MySQL ์ฐ๊ฒฐ ์ ์ถ๊ฐ ์ค์ | |
| - ํ์์กด ์ค์ | |
| - ๋ฌธ์์ ํ์ธ | |
| """ | |
| cursor = dbapi_conn.cursor() | |
| # UTF-8 ๋ฌธ์์ ๊ฐ์ ์ค์ | |
| cursor.execute("SET NAMES utf8mb4") | |
| cursor.execute("SET CHARACTER SET utf8mb4") | |
| cursor.execute("SET character_set_connection=utf8mb4") | |
| cursor.close() | |
| # ============================================================================ | |
| # ๊ฐ๋ฐ์ฉ ์ ํธ๋ฆฌํฐ | |
| # ============================================================================ | |
| if __name__ == "__main__": | |
| """ | |
| ์ง์ ์คํ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ ์คํธ | |
| ์คํ ๋ฐฉ๋ฒ: | |
| ```bash | |
| python app/database.py | |
| ``` | |
| """ | |
| print("=" * 60) | |
| print("SmartEyeSsen Database Connection Test") | |
| print("=" * 60) | |
| print(f"Database URL: {SQLALCHEMY_DATABASE_URL.replace(DB_PASSWORD, '***')}") | |
| print("-" * 60) | |
| test_connection() | |
| print("=" * 60) | |