"""device_logs source column Adds a 'source' column to device_logs distinguishing the debug log stream (vesper/{id}/logs, source='log') from the general info stream (vesper/{id}/status/info, source='info'), which was previously discarded after only being written to the server debug log. Existing rows default to 'log' since that's the only source ever persisted before this migration. Adding a column to a partitioned parent table applies it to all existing and future partitions automatically. Revision ID: e5f6a7b8c9d0 Revises: d4e5f6a7b8c9 Create Date: 2026-07-14 00:00:00.000000 """ from typing import Sequence, Union import sqlalchemy as sa from alembic import op revision: str = "e5f6a7b8c9d0" down_revision: Union[str, None] = "d4e5f6a7b8c9" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.execute(""" ALTER TABLE device_logs ADD COLUMN source TEXT NOT NULL DEFAULT 'log' """) op.execute(""" CREATE INDEX idx_device_logs_source ON device_logs(device_serial, source, received_at DESC) """) def downgrade() -> None: op.execute("DROP INDEX IF EXISTS idx_device_logs_source") op.execute("ALTER TABLE device_logs DROP COLUMN source")