You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
buffer_platform/app/analysis_db.py

104 lines
3.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
期货智析数据库 - 独立存储
"""
import logging
from pathlib import Path
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from datetime import datetime
from app.mysql_database import MySQLSessionLocal
from app.storage_manager import get_storage_manager
logger = logging.getLogger(__name__)
# 数据目录
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
DATA_DIR.mkdir(parents=True, exist_ok=True)
ANALYSIS_DB_PATH = DATA_DIR / "futures_analysis.db"
analysis_engine = create_engine(
f"sqlite:///{ANALYSIS_DB_PATH}",
connect_args={"check_same_thread": False},
pool_pre_ping=True,
)
AnalysisSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=analysis_engine)
AnalysisBase = declarative_base()
def get_analysis_db():
"""获取期货智析数据库会话。
根据 MySQL 可用性动态选择后端:
- MySQL 可用时返回 MySQL Session
- MySQL 不可用时返回 SQLite Session兜底
"""
storage = get_storage_manager()
if MySQLSessionLocal is not None and storage.check_mysql():
try:
db = MySQLSessionLocal()
yield db
finally:
db.close()
else:
db = AnalysisSessionLocal()
try:
yield db
finally:
db.close()
def init_analysis_db():
"""初始化期货智析数据库表SQLite 兜底)。"""
# 确保导入所有模型类,使其注册到 AnalysisBase
from app import analysis_models
# 直接导入 analysis_models 模块中的所有类
from app.analysis_models import (
FuturesAnalysis, WatchedSymbol, AIModelConfig, AnalysisSettings,
AIAnalysisCache, ReviewDate, SymbolRanking, TradingPlan,
SymbolScoreV2, TradingPlanV2, SectorHeat, ReviewPlanV2,
TradeRecord, TradeImportBatch,
)
AnalysisBase.metadata.create_all(bind=analysis_engine)
# 迁移为已有表添加新增列SQLite 不支持 IF NOT EXISTS用异常处理
_migrate_add_columns()
def init_analysis_mysql(mysql_engine):
"""初始化期货智析数据库表MySQL"""
from app import analysis_models
from app.analysis_models import (
FuturesAnalysis, WatchedSymbol, AIModelConfig, AnalysisSettings,
AIAnalysisCache, ReviewDate, SymbolRanking, TradingPlan,
SymbolScoreV2, TradingPlanV2, SectorHeat, ReviewPlanV2,
TradeRecord, TradeImportBatch,
)
AnalysisBase.metadata.create_all(bind=mysql_engine)
logger.info("MySQL analysis 表结构初始化完成")
def _migrate_add_columns():
"""为已有表添加新增列(兼容旧数据库)"""
import sqlite3
conn = sqlite3.connect(str(ANALYSIS_DB_PATH))
cursor = conn.cursor()
migrations = [
("symbol_scores_v2", "data_date", "VARCHAR(16)"),
("review_plans_v2", "actual_data_date", "VARCHAR(16)"),
("review_plans_v2", "data_date_matches", "INTEGER"),
]
for table, column, col_type in migrations:
try:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN {column} {col_type}")
except sqlite3.OperationalError:
pass # 列已存在
conn.commit()
conn.close()