Files
QuantEngineByItz/tools/verify_table_coverage.py
kjh2064 a7c28f240d WBS-8.1/9.2/9.6: 데이터 로드 및 웹 UI 테스트 완료
### 데이터 로드 (100% 커버리지)
- GatherTradingData.xlsx에서 20개 시트 추출 (7,495 rows)
- kis_data_collection.db: data_feed 26 rows
- snapshot_admin.db: 26개 테이블 (settings, account_snapshot, alpha_history 등)

### 로더 스크립트 (5개)
- load_from_xlsx.py: XLSX 전체 로드 (pandas 기반)
- load_settings_properly.py: settings key-value 형태 정확히 로드
- load_all_trading_data.py: JSON 부분 로드 (초기)
- load_complete_trading_data.py: JSON 완전 로드 시도 (구조 문제)
- verify_table_coverage.py: 테이블 커버리지 검증

### 웹 UI 테스트
- 서버: 포트 5000에서 실행 중
- API /api/table_rows: settings 조회 완료
- 수정 기능: DB 직접 수정 확인 (orbit_start_asset_krw 250M→300M)

### WBS 완료 현황
✓ WBS-8.1: T+20 모니터링 (2,711개 거래 기록, 목표 30개 초과 달성)
✓ WBS-9.2: 성능 최적화 (WAL 모드, 5개 인덱스)
✓ WBS-9.6: LLM Radar Phase 3-5 (5단계 구현)

### 주요 설정값 (현재)
- 포트폴리오 시작 자산: 300,000,000 (수정됨)
- 포트폴리오 목표 자산: 600,000,000 (수정됨)
- 현재 총자산: 431,266,207
- 예수금: 13,213,373

### 다음 단계
- WBS-9.3: NULL 정책 강제 (20% 추가)
- WBS-9.7: Gitea CI/CD 백업 (20% 추가)
- API 편집 기능: /api/settings/save 구현 (500 에러 해결 필요)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-23 00:52:26 +09:00

105 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""
DB 테이블 커버리지 검증
GatherTradingData.json의 시트 vs 현재 DB 테이블 비교
"""
import json
import sqlite3
from pathlib import Path
def get_xlsx_sheets():
"""GatherTradingData.json에서 시트 목록 추출"""
try:
with open('GatherTradingData.json', encoding='utf-8') as f:
full_data = json.load(f)
sheets = full_data.get('metadata', {}).get('sheets_included', [])
return sheets
except:
try:
with open('GatherTradingData.json', encoding='euc-kr') as f:
full_data = json.load(f)
sheets = full_data.get('metadata', {}).get('sheets_included', [])
return sheets
except:
return []
def get_db_tables():
"""DB의 현재 테이블 조회"""
tables = {}
for db_name, db_path in [
("kis_data_collection", "src/quant_engine/kis_data_collection.db"),
("snapshot_admin", "src/quant_engine/snapshot_admin.db")
]:
if not Path(db_path).exists():
continue
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
db_tables = [row[0] for row in cursor.fetchall() if row[0] != 'sqlite_sequence']
conn.close()
tables[db_name] = db_tables
return tables
def main():
print("="*80)
print("데이터베이스 테이블 커버리지 검증")
print("="*80)
# XLSX 시트
xlsx_sheets = get_xlsx_sheets()
print(f"\n[GatherTradingData.json]")
print(f"총 시트 수: {len(xlsx_sheets)}")
print("시트 목록:")
for i, sheet in enumerate(xlsx_sheets, 1):
print(f" {i:2}. {sheet}")
# DB 테이블
db_tables = get_db_tables()
total_tables = sum(len(t) for t in db_tables.values())
print(f"\n[현재 DB]")
print(f"총 테이블 수: {total_tables}")
for db_name, tables in db_tables.items():
print(f"\n{db_name}.db:")
for table in tables:
print(f" - {table}")
# 비교
print("\n" + "="*80)
print("커버리지 분석")
print("="*80)
all_db_tables = []
for tables in db_tables.values():
all_db_tables.extend(tables)
covered = [s for s in xlsx_sheets if s.lower() in [t.lower() for t in all_db_tables]]
missing = [s for s in xlsx_sheets if s.lower() not in [t.lower() for t in all_db_tables]]
coverage = (len(covered) / len(xlsx_sheets) * 100) if xlsx_sheets else 0
print(f"\n[결과]")
print(f" 커버된 시트: {len(covered)}/{len(xlsx_sheets)} ({coverage:.1f}%)")
print(f" 누락된 시트: {len(missing)}")
if missing:
print(f"\n[누락된 시트]")
for sheet in missing:
print(f" - {sheet}")
print(f"\n[권장]")
print("다음 테이블들을 추가하여 커버리지를 완성해야 함:")
for sheet in missing[:10]:
print(f" - {sheet}")
if len(missing) > 10:
print(f" ... 및 {len(missing)-10}개 추가")
if __name__ == "__main__":
main()