diff --git a/src/infra/src/table/mod.rs b/src/infra/src/table/mod.rs index 18b6a08d89..beb7176447 100644 --- a/src/infra/src/table/mod.rs +++ b/src/infra/src/table/mod.rs @@ -42,12 +42,36 @@ pub async fn init() -> Result<(), anyhow::Error> { pub async fn migrate() -> Result<(), anyhow::Error> { let locker = dist_lock::lock("/database/migration", 0).await?; let client = ORM_CLIENT.get_or_init(connect_to_orm).await; - Migrator::up(client, Some(12)).await?; // hack for failing alerts migration + // This is a hack to fix the failing alerts migration + // For postgres, we need to run the migration that populates the alerts table first. + // Otherwise, the `m20250109_092400_recreate_tables_with_ksuids` migration will fail. + let first_stage = get_alerts_populate_migration_index().await?; + Migrator::up(client, Some(first_stage)).await?; // hack for failing alerts migration Migrator::up(client, None).await?; dist_lock::unlock(&locker).await?; Ok(()) } +/// Get the index of the migration that populates the alerts table. +/// This index is used as the first stage of the migration process. +async fn get_alerts_populate_migration_index() -> Result { + let client = ORM_CLIENT.get_or_init(connect_to_orm).await; + let migrations = Migrator::get_pending_migrations(client).await?; + let mut index: u32 = 0; + for (i, migration) in migrations.iter().enumerate() { + if migration.name() == "m20241217_155000_populate_alerts_table" { + index = i as u32 + 1; + break; + } + } + // If the migration is not found, it is already applied so return 0 + log::debug!( + "Migration m20241217_155000_populate_alerts_table at step {} (0 means already applied)", + index + ); + Ok(index) +} + pub async fn down(steps: Option) -> Result<(), anyhow::Error> { let client = ORM_CLIENT.get_or_init(connect_to_orm).await; Migrator::down(client, steps).await?;