fix:修复完成了数据库问题,已经可以正常导入数据。
This commit is contained in:
@@ -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
|
||||||
conn = get_pg_connection()
|
|
||||||
try:
|
|
||||||
import os as _os
|
import os as _os
|
||||||
|
import re as _re
|
||||||
|
|
||||||
# 尝试使用 sqlparse 按语句拆分 (处理含分号的字符串字面量、函数体等)
|
schema_path = _os.path.join(
|
||||||
try:
|
_os.path.dirname(_os.path.abspath(__file__)), "schema.sql"
|
||||||
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:
|
with open(schema_path, "r", encoding="utf-8") as f:
|
||||||
ddl_sql = f.read()
|
ddl_sql = f.read()
|
||||||
|
|
||||||
if _USE_SQLPARSE:
|
# 先去掉单行注释,再按分号分句
|
||||||
raw_statements = _sqlparse.split(ddl_sql)
|
ddl_sql = _re.sub(r"^\s*--.*$", "", ddl_sql, flags=_re.MULTILINE)
|
||||||
statements = [
|
statements = [s.strip() for s in ddl_sql.split(";") if s.strip()]
|
||||||
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
|
|
||||||
|
|
||||||
|
conn = get_pg_connection()
|
||||||
|
try:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
for stmt in statements:
|
for stmt in statements:
|
||||||
if stmt and not stmt.startswith("--"):
|
|
||||||
try:
|
|
||||||
cursor.execute(stmt)
|
cursor.execute(stmt)
|
||||||
except Exception as e:
|
conn.commit()
|
||||||
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. 获取所有股票列表 (辅助)
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user