Fix PostgreSQL init_db: rollback after benign schema migration errors.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -56,7 +56,7 @@ from kline_store import ensure_kline_tables
|
||||
from kline_stream import kline_hub, sse_format
|
||||
from kline_chart import generate_review_kline_chart, fetch_market_klines, MARKET_PERIODS
|
||||
from market import get_price as market_get_price, set_ths_refresh_token, get_quote_source_label
|
||||
from db_conn import OperationalError, connect_db, database_label, is_benign_migration_error, is_db_contention_error
|
||||
from db_conn import OperationalError, connect_db, database_label, is_benign_migration_error, is_db_contention_error, is_schema_migration_error, rollback_if_postgres
|
||||
from admin_settings import save_admin_credentials
|
||||
from db_backup import (
|
||||
backup_dir,
|
||||
@@ -373,8 +373,9 @@ def init_db():
|
||||
try:
|
||||
c.execute(sql)
|
||||
except Exception as exc:
|
||||
if not is_benign_migration_error(exc):
|
||||
if not is_schema_migration_error(exc):
|
||||
raise
|
||||
rollback_if_postgres(conn)
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS review_records
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
open_time TEXT, close_time TEXT,
|
||||
@@ -427,8 +428,9 @@ def init_db():
|
||||
try:
|
||||
c.execute(sql)
|
||||
except Exception as exc:
|
||||
if not is_benign_migration_error(exc):
|
||||
if not is_schema_migration_error(exc):
|
||||
raise
|
||||
rollback_if_postgres(conn)
|
||||
ensure_kline_tables(conn)
|
||||
init_strategy_tables(conn)
|
||||
from risk.account_risk_lib import ensure_account_risk_schema
|
||||
|
||||
+23
-2
@@ -92,6 +92,13 @@ def adapt_sql(sql: str) -> str:
|
||||
|
||||
def is_benign_migration_error(exc: BaseException) -> bool:
|
||||
"""ALTER TABLE 重复列等初始化迁移可忽略的错误。"""
|
||||
if is_schema_migration_error(exc):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_schema_migration_error(exc: BaseException) -> bool:
|
||||
"""init_db 增量迁移:缺表/缺列/重复列均可忽略。"""
|
||||
msg = str(exc).lower()
|
||||
if any(
|
||||
x in msg
|
||||
@@ -99,18 +106,32 @@ def is_benign_migration_error(exc: BaseException) -> bool:
|
||||
"duplicate column",
|
||||
"already exists",
|
||||
"duplicate key",
|
||||
"no such table",
|
||||
"does not exist",
|
||||
"undefined table",
|
||||
"undefined column",
|
||||
)
|
||||
):
|
||||
return True
|
||||
if isinstance(exc, sqlite3.OperationalError) and "duplicate column" in msg:
|
||||
if isinstance(exc, sqlite3.OperationalError) and (
|
||||
"duplicate column" in msg or "no such table" in msg
|
||||
):
|
||||
return True
|
||||
if _PSYCOPG_OK and isinstance(exc, PgOperationalError):
|
||||
code = getattr(exc, "sqlstate", "") or ""
|
||||
if code in ("42701", "42P07"): # duplicate_column, duplicate_table
|
||||
if code in ("42701", "42P07", "42P01", "42703"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def rollback_if_postgres(conn: "DbConnection") -> None:
|
||||
if is_postgres():
|
||||
try:
|
||||
conn.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class DbCursor:
|
||||
"""统一 cursor:兼容 sqlite3 的 execute / fetchone / lastrowid。"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user