"""drop notes.title and note_revisions.title — a note's name is its first line Revision ID: 0026 Revises: 0025 Create Date: 2026-08-22 A note's name is its first non-empty body line, carried by `display_title`. `notes.search_vector` is a stored generated column over `title` (0005, weight A), and Postgres won't drop a column a generated one depends on. So it is recreated over `display_title`, keeping the name ranked above the body. That recomputes every row and rebuilds the GIN index, which takes a while on a large table. `display_title` was already derived from the title, so every note keeps its name. """ from alembic import op import sqlalchemy as sa revision = "0026" down_revision = "0025" branch_labels = None depends_on = None def upgrade() -> None: # Order matters: the generated column depends on `title`, so it goes first. op.execute("DROP INDEX IF EXISTS ix_notes_search") op.execute("ALTER TABLE notes DROP COLUMN IF EXISTS search_vector") op.drop_column("notes", "title") op.drop_column("note_revisions", "title") op.execute( """ ALTER TABLE notes ADD COLUMN search_vector tsvector GENERATED ALWAYS AS ( setweight(to_tsvector('english', coalesce(display_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") # Comes back empty. The text is not gone — it is the first line of every body — # but which notes once had an explicit title is not recorded anywhere. op.add_column("notes", sa.Column("title", sa.Text(), nullable=True)) op.add_column("note_revisions", sa.Column("title", sa.Text(), nullable=True)) 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)")