From 8a4750c45e04862cac91236c3a43e320775f897c Mon Sep 17 00:00:00 2001 From: bnair123 Date: Sat, 27 Dec 2025 23:43:25 +0400 Subject: [PATCH] Fix UI DuckDB concurrent access with read-only mode - Add read_only parameter to DataStorage.connect() - UI now connects in read-only mode to avoid lock conflicts with engine --- src/tradefinder/data/storage.py | 12 +++++++----- src/tradefinder/ui/app.py | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tradefinder/data/storage.py b/src/tradefinder/data/storage.py index 397d4af..22fd612 100644 --- a/src/tradefinder/data/storage.py +++ b/src/tradefinder/data/storage.py @@ -27,22 +27,24 @@ class DataStorage: storage.disconnect() """ - def __init__(self, db_path: Path) -> None: + def __init__(self, db_path: Path, *, read_only: bool = False) -> None: """Initialize storage with database path. Args: db_path: Path to DuckDB database file + read_only: If True, open database in read-only mode (no locking) """ self.db_path = db_path + self._read_only = read_only self._conn: duckdb.DuckDBPyConnection | None = None def connect(self) -> None: """Connect to the database.""" - # Ensure parent directory exists - self.db_path.parent.mkdir(parents=True, exist_ok=True) + if not self._read_only: + self.db_path.parent.mkdir(parents=True, exist_ok=True) - self._conn = duckdb.connect(str(self.db_path)) - logger.info("Connected to DuckDB", path=str(self.db_path)) + self._conn = duckdb.connect(str(self.db_path), read_only=self._read_only) + logger.info("Connected to DuckDB", path=str(self.db_path), read_only=self._read_only) def disconnect(self) -> None: """Close database connection.""" diff --git a/src/tradefinder/ui/app.py b/src/tradefinder/ui/app.py index b8ccd85..d019456 100644 --- a/src/tradefinder/ui/app.py +++ b/src/tradefinder/ui/app.py @@ -33,7 +33,7 @@ def get_storage() -> DataStorage | None: if not db_path.exists(): return None - storage = DataStorage(db_path) + storage = DataStorage(db_path, read_only=True) storage.connect() return storage