113 lines
3.9 KiB
Python
113 lines
3.9 KiB
Python
"""
|
|
Dashboard Migration
|
|
|
|
dashboard 테이블 초기화 및 기존 데이터 마이그레이션을 담당합니다.
|
|
서버 기동 시 create_db_tables() 이후 호출됩니다.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from sqlalchemy import func, select, text
|
|
from sqlalchemy.dialects.mysql import insert
|
|
|
|
from app.dashboard.models import Dashboard
|
|
from app.database.session import AsyncSessionLocal, engine
|
|
from app.social.models import SocialUpload
|
|
from app.user.models import SocialAccount
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def _dashboard_table_exists() -> bool:
|
|
"""dashboard 테이블 존재 여부 확인"""
|
|
async with engine.connect() as conn:
|
|
result = await conn.execute(
|
|
text(
|
|
"SELECT COUNT(*) FROM information_schema.tables "
|
|
"WHERE table_schema = DATABASE() AND table_name = 'dashboard'"
|
|
)
|
|
)
|
|
return result.scalar() > 0
|
|
|
|
|
|
async def _dashboard_is_empty() -> bool:
|
|
"""dashboard 테이블 데이터 존재 여부 확인"""
|
|
async with AsyncSessionLocal() as session:
|
|
result = await session.execute(
|
|
select(func.count()).select_from(Dashboard)
|
|
)
|
|
return result.scalar() == 0
|
|
|
|
|
|
async def _migrate_existing_data() -> None:
|
|
"""
|
|
SocialUpload(status=completed) → Dashboard 마이그레이션.
|
|
INSERT IGNORE로 중복 안전하게 삽입.
|
|
"""
|
|
async with AsyncSessionLocal() as session:
|
|
result = await session.execute(
|
|
select(
|
|
SocialUpload.user_uuid,
|
|
SocialUpload.platform,
|
|
SocialUpload.platform_video_id,
|
|
SocialUpload.platform_url,
|
|
SocialUpload.title,
|
|
SocialUpload.uploaded_at,
|
|
SocialAccount.platform_user_id,
|
|
)
|
|
.join(SocialAccount, SocialUpload.social_account_id == SocialAccount.id)
|
|
.where(
|
|
SocialUpload.status == "completed",
|
|
SocialUpload.platform_video_id.isnot(None),
|
|
SocialUpload.uploaded_at.isnot(None),
|
|
SocialAccount.platform_user_id.isnot(None),
|
|
)
|
|
)
|
|
rows = result.all()
|
|
|
|
if not rows:
|
|
logger.info("[DASHBOARD_MIGRATE] 마이그레이션 대상 없음")
|
|
return
|
|
|
|
async with AsyncSessionLocal() as session:
|
|
for row in rows:
|
|
stmt = (
|
|
insert(Dashboard)
|
|
.values(
|
|
user_uuid=row.user_uuid,
|
|
platform=row.platform,
|
|
platform_user_id=row.platform_user_id,
|
|
platform_video_id=row.platform_video_id,
|
|
platform_url=row.platform_url,
|
|
title=row.title,
|
|
uploaded_at=row.uploaded_at,
|
|
)
|
|
.prefix_with("IGNORE")
|
|
)
|
|
await session.execute(stmt)
|
|
await session.commit()
|
|
|
|
logger.info(f"[DASHBOARD_MIGRATE] 마이그레이션 완료 - {len(rows)}건 삽입")
|
|
|
|
|
|
async def init_dashboard_table() -> None:
|
|
"""
|
|
dashboard 테이블 초기화 진입점.
|
|
|
|
- 테이블이 없으면 생성 후 마이그레이션
|
|
- 테이블이 있지만 비어있으면 마이그레이션 (DEBUG 모드에서 create_db_tables()가 빈 테이블 생성한 경우)
|
|
- 테이블이 있고 데이터도 있으면 스킵
|
|
"""
|
|
if not await _dashboard_table_exists():
|
|
logger.info("[DASHBOARD_MIGRATE] dashboard 테이블 없음 - 생성 및 마이그레이션 시작")
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(
|
|
lambda c: Dashboard.__table__.create(c, checkfirst=True)
|
|
)
|
|
await _migrate_existing_data()
|
|
elif await _dashboard_is_empty():
|
|
logger.info("[DASHBOARD_MIGRATE] dashboard 테이블 비어있음 - 마이그레이션 시작")
|
|
await _migrate_existing_data()
|
|
else:
|
|
logger.info("[DASHBOARD_MIGRATE] dashboard 테이블 이미 존재 - 스킵")
|