Repository navigation
Make pgvector and the model registry schema-aware; fix sqlite-vec's engine reconstruction - #57
Conversation
…urator, adaption of the config, update CI
…figurator, guard schemas properly
… schema across databases
gkennos
left a comment
There was a problem hiding this comment.
This PR imports new oa-configurator schema helpers and depends on the corresponding omop-alchemy table-role changes, but pyproject.toml still accepts any oa-configurator>=1,<2 and omop-alchemy>=1,<2. That permits clean installs which satisfy metadata while lacking the interfaces and semantics used here.
Please set the lower bounds to the first releases containing the assumed fixes, refresh the lockfile, and add a composed compatibility job using those exact artifacts. Also coordinate this package's major version with omop-graph's optional dependency range so graph can actually install the release that contains these breaking changes.
…lways writes and there is no reason to have read-only access at the moment
…N resolving, Remove old metric/index guided mechanisms and plumbing that not longer is required
…, explicit verification of registration schema
|
Since the last review: registry rows are now keyed by the owning vector-store entry, so two stores sharing one physical database never see each other's models. The reader now fails closed on a misplaced registry the same way the writer already did. |
There was a problem hiding this comment.
🟡 Changes recommended
Dependency declarations, registry validation, registration ordering, and fail-closed behavior contain unresolved correctness issues.
8 open findings
Update dependencies for new schema APIs · New Validate all required registry columns · New Detect misplaced registries in other schemas · New Require and validate all sidecar metadata · New Raise when registered storage table is missing · New Close search reader resources · New Replace unreleased migration URL placeholder · New Import Capabilities in example · New
What changed in this PR
Makes vector stores and the model registry schema-aware, introduces explicit reader/writer access, and improves pgvector/sqlite-vec lifecycle handling.
Changes:
- Adds reserved-schema registry management and per-store model scoping.
- Splits read-only and writable store opening paths.
- Reworks index, population, filtering, bundle, and test infrastructure.
| File | Description |
|---|---|
src/omop_emb/backends/base_backend.py |
Adds reader/writer lifecycle and storage guards. |
tests/test_sqlitevec.py |
Updates sqlite-vec lifecycle coverage. |
tests/test_schema_provenance_guard.py |
Tests schema-drift protection. |
tests/test_resolve_backend.py |
Tests writer backend resolution. |
tests/test_registry.py |
Expands registry-layout coverage. |
tests/test_registry_location.py |
Tests misplaced registries. |
tests/test_read_only_population.py |
Tests read-only population flows. |
tests/test_pgvector.py |
Expands schema and index coverage. |
tests/test_pgvector_index_sql.py |
Tests new index SQL helpers. |
tests/test_pgvector_index_manager.py |
Removes obsolete manager tests. |
tests/test_pgvector_descriptor.py |
Tests descriptor isolation. |
tests/test_metric_checks.py |
Tests query-only metric validation. |
tests/test_in_values.py |
Tests large single-parameter filters. |
tests/test_faiss_cache.py |
Updates FAISS metadata coverage. |
tests/test_embedding_generation.py |
Uses routed CDM sessions. |
tests/test_embedding_bundle.py |
Adds bundle-version compatibility tests. |
tests/test_config.py |
Tests unsupported backend handling. |
tests/test_cli_search.py |
Tests optional CDM enrichment. |
tests/test_cli_pgvector_snapshot.py |
Updates registry query tests. |
tests/shared_backend_tests.py |
Adapts shared backend contracts. |
tests/conftest.py |
Reworks database fixtures. |
src/omop_emb/utils/errors.py |
Adds registry and read-only errors. |
src/omop_emb/utils/embedding_utils.py |
Updates CDM session terminology. |
src/omop_emb/utils/cdm.py |
Introduces routed session factories. |
src/omop_emb/storage/faiss/faiss_cache.py |
Adds dedicated cache metadata. |
src/omop_emb/population.py |
Uses reader and routed sessions. |
src/omop_emb/model_registry/model_registry_types.py |
Documents scoped storage identifiers. |
src/omop_emb/model_registry/model_registry_orm.py |
Adds reserved-schema registry handling. |
src/omop_emb/model_registry/model_registry_manager.py |
Adds scoped, atomic registration. |
src/omop_emb/model_registry/__init__.py |
Exports new registry APIs. |
src/omop_emb/config.py |
Adds registry and CDM helpers. |
src/omop_emb/cli/cli_maintenance.py |
Uses reader/writer store APIs. |
src/omop_emb/cli/cli_embeddings.py |
Uses routed CDM and store access. |
src/omop_emb/cli/cli_diagnostics.py |
Updates read-only diagnostics. |
src/omop_emb/backends/sqlitevec/sqlitevec_sql.py |
Replaces temporary-table filtering. |
src/omop_emb/backends/sqlitevec/sqlitevec_backend.py |
Uses resolved engines and read-only mode. |
src/omop_emb/backends/sqlitevec/__init__.py |
Removes engine factory export. |
src/omop_emb/backends/read_only.py |
Removes legacy read-only wrapper. |
src/omop_emb/backends/pgvector/pg_sql.py |
Adds schema-aware DDL and filtering. |
src/omop_emb/backends/pgvector/pg_index_manager.py |
Removes obsolete index managers. |
src/omop_emb/backends/pgvector/pg_backend.py |
Reworks pgvector indexing and access. |
src/omop_emb/backends/pgvector/__init__.py |
Removes manager exports. |
src/omop_emb/backends/index_config.py |
Generalizes config deserialization. |
src/omop_emb/backends/embedding_table.py |
Adds metadata comparison behavior. |
src/omop_emb/backends/db_utils.py |
Adds dialect-specific bound-list filtering. |
src/omop_emb/backends/base_index_manager.py |
Removes obsolete abstraction. |
src/omop_emb/backends/__init__.py |
Exports reader/writer APIs. |
src/omop_emb/__init__.py |
Updates public exports. |
pyproject.toml |
Separates default and database tests. |
docs/usage/interface-guide.md |
Documents new store interfaces. |
docs/usage/installation.md |
Updates configurator syntax. |
docs/usage/configuration.md |
Documents registry ownership. |
docs/usage/cli.md |
Documents metric-free bundles. |
docs/usage/backend-selection.md |
Updates index behavior guidance. |
Dockerfile |
Removes obsolete container definition. |
CHANGELOG.md |
Notes model ownership constraints. |
.github/workflows/ci.yml |
Splits SQLite and PostgreSQL CI. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.



Summary
What changed
table_exists, index management, and model-registry lookups all ignored the connection's configured schema, so a non-default-schema pgvector deployment silently read/wrote the wrong tables.oa-configurator's schema-aware primitives, with new non-default-schema regression coverage.MODEL_REGISTRY_SCHEMA), claimed viaSchemaClaim(schema_tag="registry", physical_schema=MODEL_REGISTRY_SCHEMA, reserved=True), independent of whichever schema the embedding store itself resolves to.database_config_name), so two stores sharing one physical database only ever see their own models.open_vector_store_writer/open_vector_store_readerreplace the old single-mode opener: the writer claims the registry schema, installs the extension, and ensures the table; the reader registers nothing, runs no DDL, and is read-only at the interface level (EmbeddingStoreReader) as well as the database level.@writesmarks every mutating method on the backend; a test asserts every public member is classified once and that subclass overrides keep the marker.MisplacedRegistryErrorwhen a registry table exists in a schema other thanMODEL_REGISTRY_SCHEMA, instead of the reader silently reporting zero models.RegistryManager.__init__verifies the registry's schema claim at construction instead of discovering a problem on first use.resolve_registry_schema()renamedresolve_registry_physical_schema(), matching thephysical_schema_ofnaming used stack-wide.ReadOnlyEmbeddingStore'sschema/self.schemarenamedphysical_schemathroughout to prevent ambiguity between a schema tag and a physical schema.physical_schema_ofstack-wide.test_schema_provenance_guard.py: registry-drift and primary-schema-drift regression tests against live Postgres.Removed
PGVectorEmbeddingBackend.from_db_url()(dead code, zero callers).read_only.pyand the read-only store types,resolve_backend*,create_sqlitevec_engine, the pgvector index manager and metric plumbing (superseded by the writer/reader split above).Breaking changes
create_sqlitevec_engine()is removed; pass an already-resolvedEngineto the sqlite-vec backend directly.resolve_backend()and the read-only store types are removed in favour ofopen_vector_store_writer/open_vector_store_reader.Checklist
breaking)uv run pytest -q): 181 passeduv run pytest -q -m postgresql): 59 passed