""" Embedding model — stores CLIP/SigLIP image embeddings via pgvector. Composite PK (photo_id, model) allows re-embedding with newer models without clobbering old vectors. Vector dimension is 768 to support SigLIP2 ViT-B/16 (the default). OpenCLIP ViT-B/32 (512-d) embeddings are zero-padded on insert so both models coexist in the same column. The padding is invisible to cosine similarity (zeros don't affect the angle). """ from sqlalchemy import Column, String, ForeignKey, DateTime, func from pgvector.sqlalchemy import Vector from app.database import Base class Embedding(Base): __tablename__ = 'embeddings' photo_id = Column(String, ForeignKey('photos.id', ondelete='CASCADE'), primary_key=True) model = Column(String(64), primary_key=True) # e.g. 'siglip2_vitb16' vector = Column(Vector(768)) # SigLIP2 ViT-B/16 → 768-d created_at = Column(DateTime(timezone=True), server_default=func.now())