""" 动态表管理器 处理分表创建,避免事务冲突 """ from sqlalchemy import text from sqlalchemy.orm import Session from app.core.logging_config import get_logger from app.models.work_area import WorkArea from app.models.section_data import SectionData from app.models.checkpoint import Checkpoint from app.models.measurement_data import MeasurementData logger = get_logger(__name__) class TableManager: """动态表管理器""" # 缓存已创建的表 _created_tables = set() @classmethod def ensure_table_exists(cls, db: Session, table_type: str, account_id: int) -> bool: """ 确保表存在,如果不存在则创建 使用独立连接创建表,避免与业务事务冲突 """ table_name = cls._get_table_name(table_type, account_id) cache_key = f"{table_type}_{account_id}" # 检查缓存 if cache_key in cls._created_tables: return True try: # 检查表是否存在 result = db.execute(text(f"SHOW TABLES LIKE '{table_name}'")) if result.fetchone(): cls._created_tables.add(cache_key) return True # 获取建表SQL create_sql = cls._get_create_sql(table_type, account_id) if not create_sql: logger.error(f"未知的表类型: {table_type}") return False # 使用独立连接创建表(避免事务冲突) connection = db.get_bind().connect() try: connection.execute(text(create_sql)) connection.commit() cls._created_tables.add(cache_key) logger.info(f"动态创建表成功: {table_name}") return True finally: connection.close() except Exception as e: logger.error(f"创建表失败 {table_name}: {e}") return False @classmethod def _get_table_name(cls, table_type: str, account_id: int) -> str: """获取表名""" table_map = { "work_area": WorkArea.get_table_name, "section_data": SectionData.get_table_name, "checkpoint": Checkpoint.get_table_name, "measurement_data": MeasurementData.get_table_name, } return table_map.get(table_type, lambda x: "")(account_id) @classmethod def _get_create_sql(cls, table_type: str, account_id: int) -> str: """获取建表SQL""" sql_map = { "work_area": WorkArea.get_create_sql, "section_data": SectionData.get_create_sql, "checkpoint": Checkpoint.get_create_sql, "measurement_data": MeasurementData.get_create_sql, } return sql_map.get(table_type, lambda x: "")(account_id) @classmethod def clear_cache(cls): """清除表缓存""" cls._created_tables.clear()