diff --git a/quantitative_data/importer.py b/quantitative_data/importer.py index c82f734..a7b3d13 100644 --- a/quantitative_data/importer.py +++ b/quantitative_data/importer.py @@ -856,18 +856,54 @@ def init_database(): if s.strip() and not s.strip().startswith("--") ] + # 按依赖关系排序:CREATE TABLE → CREATE INDEX → COMMENT ON → CREATE VIEW + # 避免 sqlparse 拆分后语句乱序导致 UndefinedTable 错误 + _priority = { + "CREATE TABLE": 1, + "CREATE INDEX": 2, + "COMMENT ON": 3, + "CREATE OR REPLACE VIEW": 4, + "CREATE VIEW": 4, + } + + def _stmt_priority(s): + upper = s.upper() + for keyword, prio in _priority.items(): + if upper.startswith(keyword): + return prio + return 99 # 兜底:最后执行 + + statements.sort(key=_stmt_priority) + + # 设置 autocommit 模式:每条 DDL 独立事务,互不影响 + # 否则 rollback 会撤销之前已成功执行的 CREATE TABLE + conn.autocommit = True + cursor = conn.cursor() for stmt in statements: if stmt and not stmt.startswith("--"): try: cursor.execute(stmt) except Exception as e: - logger.error(f" DDL 执行失败: {str(e)[:200]}\n SQL: {stmt[:300]}") - conn.rollback() - cursor.close() - raise + stmt_upper = stmt.upper() + # 以下类型的语句失败视为可恢复的 warning,不中断整个初始化流程: + # 1. 视图创建(依赖的基础表可能尚未创建) + # 2. 索引创建(依赖的表可能尚未导入数据) + # 3. COMMENT ON(依赖的表/视图可能尚未创建) + is_recoverable = ( + "CREATE OR REPLACE VIEW" in stmt_upper + or "CREATE VIEW" in stmt_upper + or "CREATE INDEX" in stmt_upper + or "COMMENT ON" in stmt_upper + ) + if is_recoverable: + logger.warning(f" DDL 暂跳过(依赖尚未就绪): {str(e)[:150]}\n SQL: {stmt[:200]}") + else: + logger.error(f" DDL 执行失败: {str(e)[:200]}\n SQL: {stmt[:300]}") + cursor.close() + conn.close() + raise - conn.commit() cursor.close() logger.info(" Schema 初始化完成") except Exception as e: