Last active
December 17, 2025 20:38
-
-
Save 0xC0A1/bdb949827d0347bbfbb8c0ee9539cc39 to your computer and use it in GitHub Desktop.
Aurora Dsql Migrator for Sea Orm 2. Use this if you're having issues running transactions on Aurora Dsql, this will run the migrations outside of a transaction context so it's pretty safe to point your tooling to Aurora Dsql like you'd do with PostgresSql.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use sea_orm_migration::prelude::*; | |
| pub struct AuroraDsqlMigrator; | |
| impl AuroraDsqlMigrator { | |
| pub async fn up<'c, C, M>(db: C, steps: Option<u32>) -> Result<(), DbErr> | |
| where | |
| C: IntoSchemaManagerConnection<'c>, | |
| M: MigratorTrait, | |
| { | |
| let db = db.into_schema_manager_connection(); | |
| let manager = SchemaManager::new(db); | |
| Self::up_with_manager::<M>(&manager, steps).await | |
| } | |
| pub async fn down<'c, C, M>(db: C, steps: Option<u32>) -> Result<(), DbErr> | |
| where | |
| C: IntoSchemaManagerConnection<'c>, | |
| M: MigratorTrait, | |
| { | |
| let db = db.into_schema_manager_connection(); | |
| let manager = SchemaManager::new(db); | |
| Self::down_with_manager::<M>(&manager, steps).await | |
| } | |
| pub async fn refresh<'c, C, M>(db: C) -> Result<(), DbErr> | |
| where | |
| C: IntoSchemaManagerConnection<'c>, | |
| M: MigratorTrait, | |
| { | |
| let db = db.into_schema_manager_connection(); | |
| let manager = SchemaManager::new(db); | |
| Self::down_with_manager::<M>(&manager, None).await?; | |
| Self::up_with_manager::<M>(&manager, None).await | |
| } | |
| pub async fn reset<'c, C, M>(db: C) -> Result<(), DbErr> | |
| where | |
| C: IntoSchemaManagerConnection<'c>, | |
| M: MigratorTrait, | |
| { | |
| let db = db.into_schema_manager_connection(); | |
| let manager = SchemaManager::new(db); | |
| Self::down_with_manager::<M>(&manager, None).await?; | |
| manager.drop_table(Table::drop().table(M::migration_table_name()).to_owned()).await?; | |
| Ok(()) | |
| } | |
| // Helper functions that take &SchemaManager | |
| pub async fn up_with_manager<M>(manager: &SchemaManager<'_>, steps: Option<u32>) -> Result<(), DbErr> | |
| where | |
| M: MigratorTrait, | |
| { | |
| M::install(manager.get_connection()).await?; | |
| let applied_models = M::get_migration_models(manager.get_connection()).await?; | |
| let applied_versions: std::collections::HashSet<String> = applied_models | |
| .into_iter() | |
| .map(|m| m.version) | |
| .collect(); | |
| let all_migrations = M::migrations(); | |
| let pending_migrations = all_migrations.into_iter().filter(|m| !applied_versions.contains(m.name())); | |
| let pending_migrations: Vec<_> = if let Some(s) = steps { | |
| pending_migrations.take(s as usize).collect() | |
| } else { | |
| pending_migrations.collect() | |
| }; | |
| for migration in pending_migrations { | |
| println!("Applying migration '{}'", migration.name()); | |
| migration.up(manager).await?; | |
| let now = std::time::SystemTime::now() | |
| .duration_since(std::time::SystemTime::UNIX_EPOCH) | |
| .unwrap(); | |
| use sea_orm::ActiveValue; | |
| use sea_orm::EntityTrait; | |
| use sea_orm_migration::seaql_migrations; | |
| seaql_migrations::Entity::insert(seaql_migrations::ActiveModel { | |
| version: ActiveValue::Set(migration.name().to_owned()), | |
| applied_at: ActiveValue::Set(now.as_secs() as i64), | |
| }) | |
| .exec(manager.get_connection()) | |
| .await?; | |
| println!("Migration '{}' has been applied", migration.name()); | |
| } | |
| Ok(()) | |
| } | |
| pub async fn down_with_manager<M>(manager: &SchemaManager<'_>, steps: Option<u32>) -> Result<(), DbErr> | |
| where | |
| M: MigratorTrait, | |
| { | |
| M::install(manager.get_connection()).await?; | |
| let applied_models = M::get_migration_models(manager.get_connection()).await?; | |
| let applied_versions: std::collections::HashSet<String> = applied_models | |
| .into_iter() | |
| .map(|m| m.version) | |
| .collect(); | |
| let all_migrations = M::migrations(); | |
| let applied_migrations = all_migrations.into_iter().filter(|m| applied_versions.contains(m.name())); | |
| // Down migrations are applied in reverse order | |
| let applied_migrations: Vec<_> = applied_migrations.collect(); | |
| let pending_migrations = applied_migrations.into_iter().rev(); | |
| let pending_migrations: Vec<_> = if let Some(s) = steps { | |
| pending_migrations.take(s as usize).collect() | |
| } else { | |
| pending_migrations.collect() | |
| }; | |
| for migration in pending_migrations { | |
| println!("Rolling back migration '{}'", migration.name()); | |
| migration.down(manager).await?; | |
| use sea_orm::EntityTrait; | |
| use sea_orm::QueryFilter; | |
| use sea_orm::ColumnTrait; | |
| use sea_orm_migration::seaql_migrations; | |
| seaql_migrations::Entity::delete_many() | |
| .filter(seaql_migrations::Column::Version.eq(migration.name())) | |
| .exec(manager.get_connection()) | |
| .await?; | |
| println!("Migration '{}' has been rolled back", migration.name()); | |
| } | |
| Ok(()) | |
| } | |
| } | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Aurora Dsql Migrator for Sea Orm 2
Use this if you're having issues running transactions on Aurora Dsql, this will run the migrations outside of a transaction context so it's pretty safe to point your tooling to Aurora Dsql like you'd do with Postgres.
Example
Here's an example on how to use it. Just override the trait default implementations for
up,down,refreshandresetcommands. Thanks to SeaOrm team for making this easy to overwrite.