Check if settings are compatible when loading a db

This commit is contained in:
Yiorgis Gozadinos 2025-07-12 20:56:49 +03:00
parent a59b38158d
commit 4444ec50da
No known key found for this signature in database
3 changed files with 89 additions and 1 deletions

View file

@ -13,6 +13,12 @@ class Store:
self.db_path: Path | Literal[":memory:"] = db_path self.db_path: Path | Literal[":memory:"] = db_path
self._connection = self.create_db() self._connection = self.create_db()
# Validate config compatibility after connection is established
from haiku.rag.store.repositories.settings import SettingsRepository
settings_repo = SettingsRepository(self)
settings_repo.validate_config_compatibility()
def create_db(self) -> sqlite3.Connection: def create_db(self) -> sqlite3.Connection:
"""Create the database and tables with sqlite-vec support for embeddings.""" """Create the database and tables with sqlite-vec support for embeddings."""
db = sqlite3.connect(self.db_path) db = sqlite3.connect(self.db_path)

View file

@ -4,6 +4,12 @@ from typing import Any
from haiku.rag.store.engine import Store from haiku.rag.store.engine import Store
class ConfigMismatchError(Exception):
"""Raised when current config doesn't match stored settings."""
pass
class SettingsRepository: class SettingsRepository:
def __init__(self, store: Store): def __init__(self, store: Store):
self.store = store self.store = store
@ -34,3 +40,39 @@ class SettingsRepository:
) )
self.store._connection.commit() self.store._connection.commit()
def validate_config_compatibility(self) -> None:
"""Check if current config is compatible with stored settings.
Raises ConfigMismatchError if there are incompatible differences.
If no settings exist, saves current config.
"""
db_settings = self.get()
if not db_settings:
# No settings in DB, save current config
self.save()
return
from haiku.rag.config import Config
current_config = Config.model_dump(mode="json")
# Critical settings that must match
critical_settings = [
"EMBEDDINGS_PROVIDER",
"EMBEDDINGS_MODEL",
"EMBEDDINGS_VECTOR_DIM",
"CHUNK_SIZE",
"CHUNK_OVERLAP",
]
errors = []
for setting in critical_settings:
if db_settings.get(setting) != current_config.get(setting):
errors.append(
f"{setting}: current={current_config.get(setting)}, stored={db_settings.get(setting)}"
)
if errors:
error_msg = f"Config mismatch detected: {'; '.join(errors)}. Consider rebuilding the database with the current configuration."
raise ConfigMismatchError(error_msg)

View file

@ -1,6 +1,14 @@
import tempfile
from pathlib import Path
import pytest
from haiku.rag.config import Config from haiku.rag.config import Config
from haiku.rag.store.engine import Store from haiku.rag.store.engine import Store
from haiku.rag.store.repositories.settings import SettingsRepository from haiku.rag.store.repositories.settings import (
ConfigMismatchError,
SettingsRepository,
)
def test_settings_table_populated_on_store_init(): def test_settings_table_populated_on_store_init():
@ -31,3 +39,35 @@ def test_settings_save_and_retrieve():
Config.CHUNK_SIZE = original_chunk_size Config.CHUNK_SIZE = original_chunk_size
store.close() store.close()
def test_config_validation_on_db_load():
"""Test that config validation fails when loading db with mismatched settings."""
# Create a temporary database file
with tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False) as tmp:
db_path = Path(tmp.name)
try:
# Create store and save settings
store1 = Store(db_path)
SettingsRepository(store1)
store1.close()
# Change config
original_chunk_size = Config.CHUNK_SIZE
Config.CHUNK_SIZE = 999
# Loading the database should raise ConfigMismatchError
with pytest.raises(ConfigMismatchError) as exc_info:
Store(db_path)
assert "CHUNK_SIZE" in str(exc_info.value)
assert "Consider rebuilding" in str(exc_info.value)
# Restore original config
Config.CHUNK_SIZE = original_chunk_size
finally:
# Cleanup
if db_path.exists():
db_path.unlink()