From 47ee9602d11d66c315d9774ebd26c1ab475b53d8 Mon Sep 17 00:00:00 2001 From: dekun Date: Wed, 1 Jul 2026 08:19:46 +0800 Subject: [PATCH] Use direct PostgreSQL connections instead of pool to fix init deploy. Co-authored-by: Cursor --- db_conn.py | 55 ++++++++---------------------------------------- requirements.txt | 1 - 2 files changed, 9 insertions(+), 47 deletions(-) diff --git a/db_conn.py b/db_conn.py index 89fa593..d770b76 100644 --- a/db_conn.py +++ b/db_conn.py @@ -17,15 +17,12 @@ DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "futures.db") _backend_lock = threading.Lock() _backend: Optional[str] = None -_pg_pool = None -_pg_pool_lock = threading.Lock() try: import psycopg from psycopg import OperationalError as PgOperationalError from psycopg import IntegrityError as PgIntegrityError from psycopg.rows import dict_row - from psycopg_pool import ConnectionPool _PSYCOPG_OK = True except ImportError: @@ -33,7 +30,6 @@ except ImportError: PgOperationalError = Exception # type: ignore[misc,assignment] PgIntegrityError = Exception # type: ignore[misc,assignment] dict_row = None # type: ignore[assignment] - ConnectionPool = None # type: ignore[misc,assignment] _PSYCOPG_OK = False OperationalError = sqlite3.OperationalError @@ -52,7 +48,7 @@ def db_backend() -> str: if url.startswith(("postgresql://", "postgres://")): if not _PSYCOPG_OK: raise RuntimeError( - "已配置 DATABASE_URL 但未安装 psycopg,请执行: pip install 'psycopg[binary]' psycopg-pool" + "已配置 DATABASE_URL 但未安装 psycopg,请执行: pip install 'psycopg[binary]'" ) _backend = "postgres" else: @@ -216,16 +212,6 @@ class DbConnection: self._conn.rollback() def close(self) -> None: - if self._backend == "postgres" and self._from_pool: - try: - self._conn.rollback() - except Exception: - pass - try: - self._conn.close() - except Exception: - pass - return try: self._conn.close() except Exception: @@ -248,38 +234,18 @@ class DbConnection: self.close() -def _pg_pool_instance() -> ConnectionPool: - global _pg_pool - if _pg_pool is not None: - return _pg_pool - with _pg_pool_lock: - if _pg_pool is not None: - return _pg_pool - url = (os.getenv("DATABASE_URL") or "").strip() - min_size = max(1, int(os.getenv("PG_POOL_MIN", "2") or 2)) - max_size = max(min_size, int(os.getenv("PG_POOL_MAX", "20") or 20)) - _pg_pool = ConnectionPool( - conninfo=url, - min_size=min_size, - max_size=max_size, - kwargs={"row_factory": dict_row}, - open=True, - ) - return _pg_pool - - def connect_db(path: str | None = None) -> DbConnection: - """获取数据库连接。PostgreSQL 使用连接池;SQLite 每次新建连接(WAL)。""" + """获取数据库连接。PostgreSQL / SQLite 均为每次新建连接(用毕 close)。""" if is_postgres(): - pool = _pg_pool_instance() - raw = pool.getconn() + url = (os.getenv("DATABASE_URL") or "").strip() + raw = psycopg.connect(url, row_factory=dict_row) try: with raw.cursor() as cur: cur.execute("SET TIME ZONE 'Asia/Shanghai'") raw.commit() except Exception: pass - return DbConnection("postgres", raw, from_pool=True) + return DbConnection("postgres", raw, from_pool=False) db_path = path or DB_PATH raw = sqlite3.connect(db_path, timeout=30, check_same_thread=False) @@ -293,11 +259,8 @@ def connect_db(path: str | None = None) -> DbConnection: def close_pg_pool() -> None: - global _pg_pool - with _pg_pool_lock: - if _pg_pool is not None: - _pg_pool.close() - _pg_pool = None + """兼容旧调用;当前 PostgreSQL 使用直连,无全局连接池。""" + return def execute_retry( @@ -365,8 +328,8 @@ def is_db_contention_error(exc: BaseException) -> bool: def reset_backend_for_tests(backend: str | None = None) -> None: - """测试用:重置后端检测与连接池。""" - global _backend, _pg_pool + """测试用:重置后端检测。""" + global _backend close_pg_pool() with _backend_lock: _backend = backend diff --git a/requirements.txt b/requirements.txt index 77f2740..3c33b37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,3 @@ vnpy_ctp>=6.7.11.4 # PostgreSQL 生产库(配置 DATABASE_URL 时启用;未配置则仍用 SQLite) psycopg[binary]>=3.2.0 -psycopg-pool>=3.2.0