fix:修复完成了数据库问题,已经可以正常导入数据。

This commit is contained in:
2026-08-01 12:56:39 +08:00
parent 7a31c29b44
commit cdf5582c90
+17 -76
View File
@@ -795,19 +795,18 @@ def init_database():
logger.info("=" * 60) logger.info("=" * 60)
logger.info("初始化数据库 Schema ...") logger.info("初始化数据库 Schema ...")
# 尝试创建数据库 (如果不存在) # 尝试创建数据库如果不存在
try: try:
admin_conn = psycopg2.connect( admin_conn = psycopg2.connect(
host=DB_CONFIG["host"], host=DB_CONFIG["host"],
port=DB_CONFIG["port"], port=DB_CONFIG["port"],
database="postgres", # 连接默认 postgres 库来创建新库 database="postgres",
user=DB_CONFIG["user"], user=DB_CONFIG["user"],
password=DB_CONFIG["password"], password=DB_CONFIG["password"],
) )
admin_conn.autocommit = True admin_conn.autocommit = True
cursor = admin_conn.cursor() cursor = admin_conn.cursor()
# 检查数据库是否存在
cursor.execute( cursor.execute(
"SELECT 1 FROM pg_database WHERE datname = %s", "SELECT 1 FROM pg_database WHERE datname = %s",
(DB_CONFIG["database"],), (DB_CONFIG["database"],),
@@ -828,82 +827,25 @@ def init_database():
logger.warning(f" 创建数据库步骤跳过 (可能无权限): {e}") logger.warning(f" 创建数据库步骤跳过 (可能无权限): {e}")
# 执行 DDL # 执行 DDL
import os as _os
import re as _re
schema_path = _os.path.join(
_os.path.dirname(_os.path.abspath(__file__)), "schema.sql"
)
with open(schema_path, "r", encoding="utf-8") as f:
ddl_sql = f.read()
# 先去掉单行注释,再按分号分句
ddl_sql = _re.sub(r"^\s*--.*$", "", ddl_sql, flags=_re.MULTILINE)
statements = [s.strip() for s in ddl_sql.split(";") if s.strip()]
conn = get_pg_connection() conn = get_pg_connection()
try: try:
import os as _os
# 尝试使用 sqlparse 按语句拆分 (处理含分号的字符串字面量、函数体等)
try:
import sqlparse as _sqlparse
_USE_SQLPARSE = True
except ImportError:
_USE_SQLPARSE = False
logger.warning(" sqlparse 未安装,回退为简单分号拆分")
schema_path = _os.path.join(_os.path.dirname(_os.path.abspath(__file__)), "schema.sql")
with open(schema_path, "r", encoding="utf-8") as f:
ddl_sql = f.read()
if _USE_SQLPARSE:
raw_statements = _sqlparse.split(ddl_sql)
statements = [
s.strip() for s in raw_statements
if s.strip() and not s.strip().startswith("--")
]
else:
statements = [
s.strip() for s in ddl_sql.split(";")
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() cursor = conn.cursor()
for stmt in statements: for stmt in statements:
if stmt and not stmt.startswith("--"): cursor.execute(stmt)
try: conn.commit()
cursor.execute(stmt)
except Exception as e:
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
cursor.close() cursor.close()
logger.info(" Schema 初始化完成") logger.info(" Schema 初始化完成")
except Exception as e: except Exception as e:
@@ -913,7 +855,6 @@ def init_database():
finally: finally:
conn.close() conn.close()
# ============================================================ # ============================================================
# 9. 获取所有股票列表 (辅助) # 9. 获取所有股票列表 (辅助)
# ============================================================ # ============================================================