diff --git a/backend/alembic/versions/ca7d3c4e8b2a_add_transportation_id_sequences.py b/backend/alembic/versions/ca7d3c4e8b2a_add_transportation_id_sequences.py new file mode 100644 index 00000000..aaff8d77 --- /dev/null +++ b/backend/alembic/versions/ca7d3c4e8b2a_add_transportation_id_sequences.py @@ -0,0 +1,67 @@ +"""add transportation id sequences + +Revision ID: ca7d3c4e8b2a +Revises: a1b2c3d4e5f6 +Create Date: 2026-05-08 08:34:00.000000 + +Crea las secuencias `a76.__seq` que los servicios de catálogos de +transporte (transporter, vehicle, driver, trailer) referencian vía +`SELECT nextval(...)`. La migración es idempotente y reposiciona cada +secuencia a `MAX()` para no chocar con filas pre-existentes. +""" +from typing import Sequence, Union + +from alembic import op + + +revision: str = "ca7d3c4e8b2a" +down_revision: Union[str, None] = "a1b2c3d4e5f6" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +# (tabla, columna_id_sustituto) en el esquema a76. El nombre de secuencia +# resultante es `a76.__seq`, que es el patrón que los +# servicios ya consumen (ver transporters/vehicles/drivers/trailers services). +_SEQUENCE_TARGETS = ( + ("transporter", "transporter_id"), + ("vehicle", "vehicle_id"), + ("driver", "driver_id"), + ("trailer", "trailer_id"), +) + + +def _seq_name(table: str, column: str) -> str: + return f"{table}_{column}_seq" + + +def upgrade() -> None: + for table, column in _SEQUENCE_TARGETS: + seq = _seq_name(table, column) + op.execute( + f'CREATE SEQUENCE IF NOT EXISTS a76."{seq}" ' + f"AS BIGINT START WITH 1 INCREMENT BY 1" + ) + # Reposicionar la secuencia al MAX(id) actual para evitar colisiones + # con datos ya cargados antes de existir la secuencia. + op.execute( + f"SELECT setval('a76.\"{seq}\"', " + f"GREATEST((SELECT COALESCE(MAX({column}), 0) FROM a76.{table}), 1), " + f"true)" + ) + op.execute( + f'ALTER SEQUENCE a76."{seq}" OWNED BY a76.{table}.{column}' + ) + op.execute( + f"ALTER TABLE a76.{table} " + f"ALTER COLUMN {column} SET DEFAULT nextval('a76.\"{seq}\"')" + ) + + +def downgrade() -> None: + for table, column in _SEQUENCE_TARGETS: + seq = _seq_name(table, column) + op.execute( + f"ALTER TABLE a76.{table} ALTER COLUMN {column} DROP DEFAULT" + ) + op.execute(f'DROP SEQUENCE IF EXISTS a76."{seq}"')