"""measurements.value nullable (#118) measurements.value: NULL = quota che il grafo di visione non ha prodotto (l'operatore la vede come NaN, esito sempre `fail`, deviazione NULL). Prima execute rifiutava con 422 l'intera acquisizione. measurements.deviation era gia' nullable. Downgrade: torna NOT NULL; FALLISCE se esistono righe con value NULL (vanno cancellate o valorizzate prima). Revision ID: 022_measurement_value_nullable Revises: 021_task_acquisition Create Date: 2026-10-28 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = '022_measurement_value_nullable' down_revision: Union[str, None] = '021_task_acquisition' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # batch_alter_table come nelle migrazioni vicine: serve a SQLite with op.batch_alter_table('measurements') as batch: batch.alter_column( 'value', existing_type=sa.DECIMAL(12, 6), nullable=True, ) def downgrade() -> None: with op.batch_alter_table('measurements') as batch: batch.alter_column( 'value', existing_type=sa.DECIMAL(12, 6), nullable=False, )