diff --git a/app/core/database.py b/app/core/database.py index 9a9fb2b..93c127c 100644 --- a/app/core/database.py +++ b/app/core/database.py @@ -3,7 +3,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from .config import settings -engine = create_engine(settings.DATABASE_URL, echo=False, pool_size=15, max_overflow=30, pool_timeout=60, pool_recycle=300) +engine = create_engine(settings.DATABASE_URL, pool_pre_ping=True, echo=False, pool_size=30, max_overflow=60, pool_timeout=30, pool_recycle=3600) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() diff --git a/app/services/original_data.py b/app/services/original_data.py index 8e25f83..8b2ef88 100644 --- a/app/services/original_data.py +++ b/app/services/original_data.py @@ -37,31 +37,50 @@ class OriginalDataService(BaseService[OriginalData]): logger.info(f"Table {table_name} already exists") return True - # 表不存在,创建表 - try: - create_table_sql = f""" - CREATE TABLE `{table_name}` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `account_id` INT NOT NULL COMMENT '账号ID', - `bfpcode` VARCHAR(1000) NOT NULL COMMENT '前(后)视点名称', - `mtime` DATETIME NOT NULL COMMENT '测点观测时间', - `bffb` VARCHAR(1000) NOT NULL COMMENT '前(后)视标记符', - `bfpl` VARCHAR(1000) NOT NULL COMMENT '前(后)视距离(m)', - `bfpvalue` VARCHAR(1000) NOT NULL COMMENT '前(后)视尺读数(m)', - `NYID` VARCHAR(100) NOT NULL COMMENT '期数id', - `sort` INT COMMENT '序号', - INDEX `idx_nyid` (`NYID`), - INDEX `idx_account_id` (`account_id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原始数据表_账号{account_id}' - """ - db.execute(text(create_table_sql)) - db.commit() - logger.info(f"Table {table_name} created successfully") - return True - except Exception as e: - db.rollback() - logger.error(f"Failed to create table {table_name}: {str(e)}") - raise Exception(f"创建原始数据表失败: {str(e)}") + # 表不存在,创建表 - 添加重试机制 + max_retries = 3 + for attempt in range(max_retries): + try: + create_table_sql = f""" + CREATE TABLE `{table_name}` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `account_id` INT NOT NULL COMMENT '账号ID', + `bfpcode` VARCHAR(1000) NOT NULL COMMENT '前(后)视点名称', + `mtime` DATETIME NOT NULL COMMENT '测点观测时间', + `bffb` VARCHAR(1000) NOT NULL COMMENT '前(后)视标记符', + `bfpl` VARCHAR(1000) NOT NULL COMMENT '前(后)视距离(m)', + `bfpvalue` VARCHAR(1000) NOT NULL COMMENT '前(后)视尺读数(m)', + `NYID` VARCHAR(100) NOT NULL COMMENT '期数id', + `sort` INT COMMENT '序号', + INDEX `idx_nyid` (`NYID`), + INDEX `idx_account_id` (`account_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原始数据表_账号{account_id}' + """ + # 使用引擎直接执行,不依赖db会话的事务 + with engine.begin() as conn: # 创建独立连接 + conn.execute(text(create_table_sql)) + + logger.info(f"Table {table_name} created successfully on attempt {attempt + 1}") + return True + + except Exception as e: + logger.warning(f"Attempt {attempt + 1} to create table {table_name} failed: {str(e)}") + + # 检查是否是表已存在错误(并发情况下可能发生) + if "already exists" in str(e).lower() or "exist" in str(e).lower(): + logger.info(f"Table {table_name} was created by another process") + return True + + if attempt == max_retries - 1: + db.rollback() # 确保回滚当前事务 + logger.error(f"Failed to create table {table_name} after {max_retries} attempts: {str(e)}") + raise Exception(f"创建原始数据表失败: {str(e)}") + + # 短暂延迟后重试 + import time + time.sleep(0.1 * (attempt + 1)) + + return False def create_table_for_account(self, db: Session, account_id: int) -> Dict[str, Any]: """ @@ -83,12 +102,20 @@ class OriginalDataService(BaseService[OriginalData]): 'message': f'账号ID {account_id} 不存在' } - # 创建表 - self._ensure_table_exists(db, account_id) - return { - 'success': True, - 'message': f'原始数据表 {self._get_table_name(account_id)} 创建成功' - } + # 创建表 - 现在使用增强的错误处理 + table_created = self._ensure_table_exists(db, account_id) + + if table_created: + return { + 'success': True, + 'message': f'原始数据表 {self._get_table_name(account_id)} 创建成功' + } + else: + return { + 'success': False, + 'message': f'原始数据表 {self._get_table_name(account_id)} 创建失败' + } + except Exception as e: logger.error(f"Failed to create table for account {account_id}: {str(e)}") return { @@ -296,13 +323,12 @@ class OriginalDataService(BaseService[OriginalData]): 'failed_items': [] } - # 确保表存在 - try: - self._ensure_table_exists(db, account_id) - except Exception as e: + # 确保表存在 - 现在使用增强的错误处理和重试机制 + table_created = self._ensure_table_exists(db, account_id) + if not table_created: return { 'success': False, - 'message': f'创建原始数据表失败: {str(e)}', + 'message': '创建原始数据表失败', 'total_count': total_count, 'success_count': 0, 'failed_count': total_count,