71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
"""Compatibility adapter for the existing direct PostgreSQL vector reader."""
|
|
|
|
from sqlalchemy import Engine
|
|
|
|
from tht.ports.vector import (
|
|
VectorCapabilities,
|
|
VectorHealth,
|
|
VectorStoreError,
|
|
VectorWriteRecord,
|
|
VectorWriteUnavailable,
|
|
require_positive_limit,
|
|
)
|
|
from tht.vectorstore.store import VectorHit, VectorStore as TableVectorStore
|
|
|
|
|
|
class LegacyDirectVectorStore:
|
|
"""Read-only port wrapper around the legacy table-scoped pgvector store."""
|
|
|
|
capabilities = VectorCapabilities(search=True, existing_hashes=False, upsert=False)
|
|
|
|
def __init__(self, engine: Engine, schema: str = "vectors", dim: int = 768):
|
|
self._engine = engine
|
|
self._schema = schema
|
|
self._dim = dim
|
|
|
|
def health(self) -> VectorHealth:
|
|
try:
|
|
with self._engine.connect() as connection:
|
|
connection.exec_driver_sql("SELECT 1")
|
|
except Exception as exc:
|
|
return VectorHealth(
|
|
ok=False,
|
|
detail=str(exc),
|
|
read_configured=True,
|
|
read_reachable=False,
|
|
read_detail=str(exc),
|
|
expected_dimension=self._dim,
|
|
)
|
|
return VectorHealth(
|
|
ok=True,
|
|
read_configured=True,
|
|
read_reachable=True,
|
|
expected_dimension=self._dim,
|
|
)
|
|
|
|
def search(
|
|
self,
|
|
collections: list[str],
|
|
embedding: list[float],
|
|
*,
|
|
limit: int,
|
|
kinds: list[str] | None = None,
|
|
metadata_filter: dict[str, object] | None = None,
|
|
) -> list[VectorHit]:
|
|
require_positive_limit(limit)
|
|
if metadata_filter is not None:
|
|
raise VectorStoreError("Legacy vector store cannot enforce metadata filtering")
|
|
hits: list[VectorHit] = []
|
|
for collection in collections:
|
|
table = TableVectorStore(
|
|
self._engine, schema=self._schema, table=collection, dim=self._dim
|
|
)
|
|
hits.extend(table.search(embedding, top_n=limit, kinds=kinds))
|
|
return sorted(hits, key=lambda hit: hit.similarity, reverse=True)[:limit]
|
|
|
|
def existing_hashes(self, collection: str, kinds: list[str]) -> dict[str, str]:
|
|
raise VectorWriteUnavailable("Legacy direct reader has no writer interface")
|
|
|
|
def upsert(self, collection: str, records: list[VectorWriteRecord]) -> int:
|
|
raise VectorWriteUnavailable("Legacy direct reader has no writer interface")
|