"""notes full-text search vector Revision ID: 0005 Revises: 0004 Create Date: 2026-07-20 A generated tsvector column (title weight A, body weight B) + GIN index, so search is index-backed and always in sync with the row (no trigger to maintain). """ from alembic import op revision = "0005" down_revision = "0004" branch_labels = None depends_on = None def upgrade() -> None: op.execute( """ ALTER TABLE notes ADD COLUMN search_vector tsvector GENERATED ALWAYS AS ( setweight(to_tsvector('english', coalesce(title, '')), 'A') || setweight(to_tsvector('english', coalesce(body, '')), 'B') ) STORED """ ) op.execute("CREATE INDEX ix_notes_search ON notes USING GIN (search_vector)") def downgrade() -> None: op.execute("DROP INDEX IF EXISTS ix_notes_search") op.execute("ALTER TABLE notes DROP COLUMN IF EXISTS search_vector")