Remove obsolete migrations
This commit is contained in:
parent
119ca84da8
commit
061095e855
5 changed files with 4 additions and 253 deletions
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
- **Dependencies**: Updated lancedb 0.26.0 → 0.26.1, docling 2.65.0 → 2.67.0
|
- **Dependencies**: Updated lancedb 0.26.0 → 0.26.1, docling 2.65.0 → 2.67.0
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- **Legacy Migrations**: Removed obsolete database migration files (`v0_9_3.py`, `v0_10_1.py`, `v0_19_6.py`). These migrations were for versions prior to 0.20.0 and are no longer needed since the current release requires a database rebuild anyway.
|
||||||
|
|
||||||
## [0.24.2] - 2026-01-08
|
## [0.24.2] - 2026-01-08
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
||||||
|
|
@ -55,14 +55,6 @@ def run_pending_upgrades(store: Store, from_version: str, to_version: str) -> No
|
||||||
|
|
||||||
# Import upgrade modules AFTER Upgrade class is defined to avoid circular imports
|
# Import upgrade modules AFTER Upgrade class is defined to avoid circular imports
|
||||||
# ruff: noqa: E402, I001
|
# ruff: noqa: E402, I001
|
||||||
from haiku.rag.store.upgrades.v0_9_3 import upgrade_fts_phrase as upgrade_0_9_3_fts
|
|
||||||
from haiku.rag.store.upgrades.v0_9_3 import upgrade_order as upgrade_0_9_3_order
|
|
||||||
from haiku.rag.store.upgrades.v0_10_1 import (
|
|
||||||
upgrade_add_title as upgrade_0_10_1_add_title,
|
|
||||||
)
|
|
||||||
from haiku.rag.store.upgrades.v0_19_6 import (
|
|
||||||
upgrade_embeddings_model_config as upgrade_0_19_6_embeddings,
|
|
||||||
)
|
|
||||||
from haiku.rag.store.upgrades.v0_20_0 import (
|
from haiku.rag.store.upgrades.v0_20_0 import (
|
||||||
upgrade_add_docling_document as upgrade_0_20_0_docling,
|
upgrade_add_docling_document as upgrade_0_20_0_docling,
|
||||||
)
|
)
|
||||||
|
|
@ -73,10 +65,6 @@ from haiku.rag.store.upgrades.v0_25_0 import (
|
||||||
upgrade_compress_docling_document as upgrade_0_25_0_compress,
|
upgrade_compress_docling_document as upgrade_0_25_0_compress,
|
||||||
)
|
)
|
||||||
|
|
||||||
upgrades.append(upgrade_0_9_3_order)
|
|
||||||
upgrades.append(upgrade_0_9_3_fts)
|
|
||||||
upgrades.append(upgrade_0_10_1_add_title)
|
|
||||||
upgrades.append(upgrade_0_19_6_embeddings)
|
|
||||||
upgrades.append(upgrade_0_20_0_docling)
|
upgrades.append(upgrade_0_20_0_docling)
|
||||||
upgrades.append(upgrade_0_23_1_contextualize)
|
upgrades.append(upgrade_0_23_1_contextualize)
|
||||||
upgrades.append(upgrade_0_25_0_compress)
|
upgrades.append(upgrade_0_25_0_compress)
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
from lancedb.pydantic import LanceModel
|
|
||||||
from pydantic import Field
|
|
||||||
|
|
||||||
from haiku.rag.store.engine import Store
|
|
||||||
from haiku.rag.store.upgrades import Upgrade
|
|
||||||
|
|
||||||
|
|
||||||
def _apply_add_document_title(store: Store) -> None: # pragma: no cover
|
|
||||||
"""Add a nullable 'title' column to the documents table."""
|
|
||||||
|
|
||||||
# Read existing rows using Arrow for schema-agnostic access
|
|
||||||
try:
|
|
||||||
docs_arrow = store.documents_table.search().to_arrow()
|
|
||||||
rows = docs_arrow.to_pylist()
|
|
||||||
except Exception:
|
|
||||||
rows = []
|
|
||||||
|
|
||||||
class DocumentRecordV2(LanceModel):
|
|
||||||
id: str
|
|
||||||
content: str
|
|
||||||
uri: str | None = None
|
|
||||||
title: str | None = None
|
|
||||||
metadata: str = Field(default="{}")
|
|
||||||
created_at: str = Field(default_factory=lambda: "")
|
|
||||||
updated_at: str = Field(default_factory=lambda: "")
|
|
||||||
|
|
||||||
# Drop and recreate documents table with the new schema
|
|
||||||
try:
|
|
||||||
store.db.drop_table("documents")
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
store.documents_table = store.db.create_table("documents", schema=DocumentRecordV2)
|
|
||||||
|
|
||||||
# Reinsert previous rows with title=None
|
|
||||||
if rows:
|
|
||||||
backfilled = []
|
|
||||||
for row in rows:
|
|
||||||
backfilled.append(
|
|
||||||
DocumentRecordV2(
|
|
||||||
id=row.get("id"),
|
|
||||||
content=row.get("content", ""),
|
|
||||||
uri=row.get("uri"),
|
|
||||||
title=None,
|
|
||||||
metadata=(
|
|
||||||
row.get("metadata")
|
|
||||||
if isinstance(row.get("metadata"), str)
|
|
||||||
else json.dumps(row.get("metadata") or {})
|
|
||||||
),
|
|
||||||
created_at=row.get("created_at", ""),
|
|
||||||
updated_at=row.get("updated_at", ""),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
store.documents_table.add(backfilled)
|
|
||||||
|
|
||||||
|
|
||||||
upgrade_add_title = Upgrade(
|
|
||||||
version="0.10.1",
|
|
||||||
apply=_apply_add_document_title,
|
|
||||||
description="Add nullable 'title' column to documents table",
|
|
||||||
)
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from haiku.rag.store.engine import SettingsRecord, Store
|
|
||||||
from haiku.rag.store.upgrades import Upgrade
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def _apply_embeddings_model_config(store: Store) -> None: # pragma: no cover
|
|
||||||
"""Migrate embeddings config from flat to nested EmbeddingModelConfig structure."""
|
|
||||||
results = list(
|
|
||||||
store.settings_table.search()
|
|
||||||
.where("id = 'settings'")
|
|
||||||
.limit(1)
|
|
||||||
.to_pydantic(SettingsRecord)
|
|
||||||
)
|
|
||||||
|
|
||||||
if not results or not results[0].settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
settings = json.loads(results[0].settings)
|
|
||||||
embeddings = settings.get("embeddings", {})
|
|
||||||
|
|
||||||
# Check if already migrated (model is a dict with nested structure)
|
|
||||||
if isinstance(embeddings.get("model"), dict):
|
|
||||||
return
|
|
||||||
|
|
||||||
# Migrate from flat structure to nested EmbeddingModelConfig
|
|
||||||
old_provider = embeddings.get("provider", "ollama")
|
|
||||||
old_model = embeddings.get("model", "qwen3-embedding:4b")
|
|
||||||
old_vector_dim = embeddings.get("vector_dim", 2560)
|
|
||||||
|
|
||||||
logger.info(
|
|
||||||
"Migrating embeddings config to new nested structure: "
|
|
||||||
"embeddings.{provider,model,vector_dim} -> embeddings.model.{provider,name,vector_dim}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create new nested structure
|
|
||||||
settings["embeddings"] = {
|
|
||||||
"model": {
|
|
||||||
"provider": old_provider,
|
|
||||||
"name": old_model,
|
|
||||||
"vector_dim": old_vector_dim,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
store.settings_table.update(
|
|
||||||
where="id = 'settings'",
|
|
||||||
values={"settings": json.dumps(settings)},
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(
|
|
||||||
"Embeddings config migrated: provider=%s, name=%s, vector_dim=%d",
|
|
||||||
old_provider,
|
|
||||||
old_model,
|
|
||||||
old_vector_dim,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
upgrade_embeddings_model_config = Upgrade(
|
|
||||||
version="0.19.6",
|
|
||||||
apply=_apply_embeddings_model_config,
|
|
||||||
description="Migrate embeddings config to nested EmbeddingModelConfig structure",
|
|
||||||
)
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
from lancedb.pydantic import LanceModel, Vector
|
|
||||||
from pydantic import Field
|
|
||||||
|
|
||||||
from haiku.rag.store.engine import Store
|
|
||||||
from haiku.rag.store.upgrades import Upgrade
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_vector_dim(store: Store) -> int: # pragma: no cover
|
|
||||||
"""Infer vector dimension from existing data; fallback to embedder config."""
|
|
||||||
try:
|
|
||||||
arrow = store.chunks_table.search().limit(1).to_arrow()
|
|
||||||
rows = arrow.to_pylist()
|
|
||||||
if rows:
|
|
||||||
vec = rows[0].get("vector")
|
|
||||||
if isinstance(vec, list) and vec:
|
|
||||||
return len(vec)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
# Fallback to configured embedder vector dim
|
|
||||||
return getattr(store.embedder, "_vector_dim", 1024)
|
|
||||||
|
|
||||||
|
|
||||||
def _apply_chunk_order(store: Store) -> None: # pragma: no cover
|
|
||||||
"""Add integer 'order' column to chunks and backfill from metadata."""
|
|
||||||
|
|
||||||
vector_dim = _infer_vector_dim(store)
|
|
||||||
|
|
||||||
class ChunkRecordV2(LanceModel):
|
|
||||||
id: str
|
|
||||||
document_id: str
|
|
||||||
content: str
|
|
||||||
metadata: str = Field(default="{}")
|
|
||||||
order: int = Field(default=0)
|
|
||||||
vector: Vector(vector_dim) = Field( # type: ignore
|
|
||||||
default_factory=lambda: [0.0] * vector_dim
|
|
||||||
)
|
|
||||||
|
|
||||||
# Read existing chunks
|
|
||||||
try:
|
|
||||||
chunks_arrow = store.chunks_table.search().to_arrow()
|
|
||||||
rows = chunks_arrow.to_pylist()
|
|
||||||
except Exception:
|
|
||||||
rows = []
|
|
||||||
|
|
||||||
new_chunk_records: list[ChunkRecordV2] = []
|
|
||||||
for row in rows:
|
|
||||||
md_raw = row.get("metadata") or "{}"
|
|
||||||
try:
|
|
||||||
md = json.loads(md_raw) if isinstance(md_raw, str) else md_raw
|
|
||||||
except Exception:
|
|
||||||
md = {}
|
|
||||||
# Extract and normalize order
|
|
||||||
order_val = 0
|
|
||||||
try:
|
|
||||||
if isinstance(md, dict) and "order" in md:
|
|
||||||
order_val = int(md["order"]) # type: ignore[arg-type]
|
|
||||||
except Exception:
|
|
||||||
order_val = 0
|
|
||||||
|
|
||||||
if isinstance(md, dict) and "order" in md:
|
|
||||||
md = {k: v for k, v in md.items() if k != "order"}
|
|
||||||
|
|
||||||
vec = row.get("vector") or [0.0] * vector_dim
|
|
||||||
|
|
||||||
new_chunk_records.append(
|
|
||||||
ChunkRecordV2(
|
|
||||||
id=row.get("id"),
|
|
||||||
document_id=row.get("document_id"),
|
|
||||||
content=row.get("content", ""),
|
|
||||||
metadata=json.dumps(md),
|
|
||||||
order=order_val,
|
|
||||||
vector=vec,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Recreate chunks table with new schema
|
|
||||||
try:
|
|
||||||
store.db.drop_table("chunks")
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
store.chunks_table = store.db.create_table("chunks", schema=ChunkRecordV2)
|
|
||||||
store.chunks_table.create_fts_index("content", replace=True)
|
|
||||||
|
|
||||||
if new_chunk_records:
|
|
||||||
store.chunks_table.add(new_chunk_records)
|
|
||||||
|
|
||||||
|
|
||||||
upgrade_order = Upgrade(
|
|
||||||
version="0.9.3",
|
|
||||||
apply=_apply_chunk_order,
|
|
||||||
description="Add 'order' column to chunks and backfill from metadata",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _apply_fts_phrase_support(store: Store) -> None: # pragma: no cover
|
|
||||||
"""Recreate FTS index with phrase query support and no stop-word removal."""
|
|
||||||
try:
|
|
||||||
store.chunks_table.create_fts_index(
|
|
||||||
"content", replace=True, with_position=True, remove_stop_words=False
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
upgrade_fts_phrase = Upgrade(
|
|
||||||
version="0.9.3",
|
|
||||||
apply=_apply_fts_phrase_support,
|
|
||||||
description="Enable FTS phrase queries (with positions) and keep stop-words",
|
|
||||||
)
|
|
||||||
Loading…
Reference in a new issue