Skip to content

Matching: signature store interface, optional Postgres store, owner decisions - #537

Merged
markusressel merged 1 commit into
masterfrom
matching-signature-store
Oct 31, 2026
Merged

markusressel merged 1 commit into
masterfrom
matching-signature-store

Conversation

@markusressel

Copy link
Copy Markdown
Owner

Summary

  • SignatureStore interface (py_image_dedup/matching/store.py) with what the pipeline needs: upsert/get by path, get_all()/iter_all() for the numpy search, get_file_states() + needs_analysis(), remove()/remove_missing(), set_full_pixel_hash(), schema_version.
  • SqliteSignatureStore: the default, lives in its own database file (separate from the web UI state store), so it can be deleted and rebuilt. SignatureStore(path) still creates a SQLite store, so existing call sites (pipeline, benchmark, tests) are unchanged.
  • PostgresSignatureStore (matching/store_postgres.py): psycopg 3, optional postgres extra ([project.optional-dependencies]), imported lazily. Persistence only, the similarity search stays in Python/numpy. Tables matching_files/matching_meta, advisory lock around schema creation, server side cursor for streaming.
  • open_signature_store(url): sqlite:///relative.db, sqlite:////abs.db, plain paths, sqlite:// (memory), postgresql://.... Ready to be wired into config.py later.
  • Schema versions: a store with another SCHEMA_VERSION is dropped and rebuilt (it is a cache).
  • Tests: tests/test_matching_store.py runs the same contract tests for SQLite (memory + file) and Postgres (integration marker, skipped without PY_IMAGE_DEDUP_TEST_POSTGRES_DSN). The CI integration job gets a Postgres service and installs the extra.
  • Docs: the owner's answers replace "Open questions" with "Decisions" in docs/matching-prototype.md, the store backends are documented, and TODO.md and AGENTS.md are updated (follow-ups: rotation/mirror matching, variants to review, crop embeddings, side-by-side matching.backend, HEIC/RAW extras, config wiring).

Test plan

  • poetry run pytest: 172 passed
  • pytest -m integration tests/test_matching_store.py against a local postgres:17-alpine: 10 passed
  • docker build . -t py-image-dedup:test (the extra is not installed in the image)

🤖 Generated with Claude Code

…ecisions

- SignatureStore interface in matching/store.py, SqliteSignatureStore (default,
  own database file, separate from the web UI state store). SignatureStore(path)
  still creates a SQLite store (backwards compatible).
- PostgresSignatureStore (psycopg 3, optional `postgres` extra, imported lazily),
  persistence only, similarity search stays in numpy.
- open_signature_store(url): sqlite:///..., plain paths, postgresql://...
- Schema version handling: a store with another schema version is rebuilt.
- Contract tests for SQLite and Postgres (integration marker,
  PY_IMAGE_DEDUP_TEST_POSTGRES_DSN), Postgres service in the CI integration job.
- docs/matching-prototype.md: owner decisions replace the open questions,
  store backends documented; TODO.md and AGENTS.md updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@markusressel
markusressel merged commit 604b03c into master Oct 31, 2026
9 checks passed
@markusressel
markusressel deleted the matching-signature-store branch October 31, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant