Check if settings are compatible when loading a db
This commit is contained in:
parent
a59b38158d
commit
4444ec50da
3 changed files with 89 additions and 1 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue