"""Performer.last_searched_at + search_run_count — backfill queue dla per-performer search. Revision ID: 0008_performer_search_meta Revises: 0007_play_progress Create Date: 2026-05-06 Continuous worker iteruje performerów ORDER BY last_searched_at NULLS FIRST, search_run_count ASC. Performerów którzy nigdy nie byli searchowani idą pierwsi. Po pełnym sweep'ie kolejka cyklicznie wraca do najstarszych. """ from collections.abc import Sequence import sqlalchemy as sa from alembic import op revision: str = "0008_performer_search_meta" down_revision: str | None = "0007_play_progress" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None def upgrade() -> None: op.add_column( "performers", sa.Column("last_searched_at", sa.DateTime(timezone=True), nullable=True), ) op.add_column( "performers", sa.Column("search_run_count", sa.Integer(), nullable=False, server_default="0"), ) # Index dla queue: NULLS FIRST + search_run_count ASC. PostgreSQL btree # default DESC ma NULLS FIRST. Asc - NULLS LAST. Robimy explicit. op.execute( "CREATE INDEX ix_performers_search_priority " "ON performers (last_searched_at ASC NULLS FIRST, search_run_count ASC)" ) def downgrade() -> None: op.drop_index("ix_performers_search_priority", table_name="performers") op.drop_column("performers", "search_run_count") op.drop_column("performers", "last_searched_at")