Stop writing the schema version on database open
This commit is contained in:
parent
e70f271ac7
commit
b6bbea3d64
3 changed files with 33 additions and 18 deletions
|
|
@ -1,6 +1,10 @@
|
|||
# Changelog
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Opening a database no longer writes to it: reads no longer rewrite the stored embedding settings or change the stored version, and the version is never downgraded.
|
||||
|
||||
## [0.54.0] - 2026-06-04
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import lancedb
|
|||
import pyarrow as pa
|
||||
from lancedb.index import FTS, BTree, IvfPq
|
||||
from lancedb.pydantic import LanceModel, Vector
|
||||
from packaging.version import parse
|
||||
from pydantic import Field
|
||||
|
||||
from haiku.rag.config import AppConfig, Config
|
||||
|
|
@ -509,7 +510,7 @@ class Store:
|
|||
await self.set_haiku_version(metadata.version("haiku.rag-slim"))
|
||||
|
||||
async def _check_migrations(self) -> None:
|
||||
"""Check if migrations are pending and error or update version accordingly.
|
||||
"""Raise if migrations are pending. Opening never writes the version.
|
||||
|
||||
Raises:
|
||||
MigrationRequiredError: If migrations are pending.
|
||||
|
|
@ -529,10 +530,6 @@ class Store:
|
|||
"Run 'haiku-rag migrate' to upgrade."
|
||||
)
|
||||
|
||||
# No pending migrations - update version silently if needed (writable only)
|
||||
if not self._read_only and db_version != current_version:
|
||||
await self.set_haiku_version(current_version)
|
||||
|
||||
async def migrate(self) -> list[str]:
|
||||
"""Run pending database migrations.
|
||||
|
||||
|
|
@ -551,8 +548,9 @@ class Store:
|
|||
|
||||
applied = await run_pending_upgrades(self, db_version)
|
||||
|
||||
# Update version after successful migration
|
||||
if applied or db_version != current_version:
|
||||
# Advance the schema marker only forward — never downgrade a database
|
||||
# opened with an older build than last stamped it.
|
||||
if parse(current_version) > parse(db_version):
|
||||
await self.set_haiku_version(current_version)
|
||||
|
||||
return applied
|
||||
|
|
|
|||
|
|
@ -38,21 +38,19 @@ class TestMigrationCheck:
|
|||
pass
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_version_bump_without_pending_migrations_updates_silently(
|
||||
self, temp_db_path
|
||||
):
|
||||
"""When version is outdated but no migrations pending, update version silently."""
|
||||
async def test_open_does_not_change_version(self, temp_db_path):
|
||||
"""Opening a database never writes the version, even when it differs.
|
||||
|
||||
A version newer than all upgrade steps has no pending migrations, so the
|
||||
open succeeds; the stored version must be left untouched (no downgrade,
|
||||
no bump) because opening is a pure read.
|
||||
"""
|
||||
async with Store(temp_db_path, create=True) as store:
|
||||
# Set an older version that has no pending migrations
|
||||
# (newer than all current upgrade steps)
|
||||
await store.set_haiku_version("100.0.0")
|
||||
|
||||
# Re-open - should update version silently, no error
|
||||
# Re-open writable - no error, version unchanged
|
||||
async with Store(temp_db_path) as store:
|
||||
# Version should now be current
|
||||
version = await store.get_haiku_version()
|
||||
expected = metadata.version("haiku.rag-slim")
|
||||
assert version == expected
|
||||
assert await store.get_haiku_version() == "100.0.0"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pending_migrations_raises_error(self, temp_db_path):
|
||||
|
|
@ -160,6 +158,21 @@ class TestMigrateMethod:
|
|||
applied = await store.migrate()
|
||||
assert applied == []
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_migrate_does_not_downgrade_future_version(self, temp_db_path):
|
||||
"""migrate() must not move the version backwards.
|
||||
|
||||
Running an older build's migrate against a DB stamped with a newer
|
||||
version (no pending upgrades) leaves the stored version untouched.
|
||||
"""
|
||||
async with Store(temp_db_path, create=True) as store:
|
||||
await store.set_haiku_version("100.0.0")
|
||||
|
||||
async with Store(temp_db_path, skip_migration_check=True) as store:
|
||||
applied = await store.migrate()
|
||||
assert applied == []
|
||||
assert await store.get_haiku_version() == "100.0.0"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_migrate_raises_read_only_error(self, temp_db_path):
|
||||
"""Store.migrate() should raise ReadOnlyError in read-only mode."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue