StocKing / database.py
adoomy's picture
feat: ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ ๋Œ“๊ธ€ ์‹œ์Šคํ…œ ์ถ”๊ฐ€ ๋ฐ DB ์—ฐ๊ฒฐ ๋ฒ„๊ทธ ์ˆ˜์ •
ffd99f4
import os
from sqlalchemy import create_engine, event, text
from sqlalchemy.orm import sessionmaker
from dotenv import load_dotenv
from models import Base
load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./stocking.db")
_is_postgres = DATABASE_URL.startswith("postgresql")
connect_args = {"sslmode": "require"} if _is_postgres else {"check_same_thread": False}
engine = create_engine(DATABASE_URL, connect_args=connect_args)
# SQLite ์ „์šฉ: WAL ๋ชจ๋“œ (PostgreSQL์—๋Š” ์ ์šฉ ์•ˆ ํ•จ)
if not _is_postgres:
@event.listens_for(engine, "connect")
def set_wal_mode(dbapi_connection, connection_record):
"""WAL ๋ชจ๋“œ: ์Šค์ผ€์ค„๋Ÿฌ write + API read ๋™์‹œ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ."""
cursor = dbapi_connection.cursor()
cursor.execute("PRAGMA journal_mode=WAL")
cursor.close()
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def init_db():
# watchlist ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜: SQLite์—๋งŒ ์ ์šฉ (PostgreSQL์€ PRAGMA ์—†์Œ)
if not _is_postgres:
with engine.connect() as conn:
cols = [row[1] for row in conn.execute(text("PRAGMA table_info(watchlist)")).fetchall()]
if cols and "user_id" not in cols:
conn.execute(text("DROP TABLE watchlist"))
conn.commit()
Base.metadata.create_all(bind=engine)
# annual_data ์ธ๋ฑ์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜: create_all์€ ๊ธฐ์กด ํ…Œ์ด๋ธ”์— ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ง์ ‘ ์ƒ์„ฑ
with engine.connect() as conn:
conn.execute(text(
"CREATE INDEX IF NOT EXISTS ix_annual_data_ticker_year_is_estimate "
"ON annual_data (ticker, year, is_estimate)"
))
conn.execute(text(
"CREATE INDEX IF NOT EXISTS ix_annual_data_ticker_is_estimate "
"ON annual_data (ticker, is_estimate)"
))
conn.commit()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()