Skip to content

Instantly share code, notes, and snippets.

@0xC0A1
Last active December 17, 2025 20:38
Show Gist options
  • Select an option

  • Save 0xC0A1/bdb949827d0347bbfbb8c0ee9539cc39 to your computer and use it in GitHub Desktop.

Select an option

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.
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(())
}
}
@0xC0A1
Copy link
Author

0xC0A1 commented Dec 17, 2025

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, refresh and reset commands. Thanks to SeaOrm team for making this easy to overwrite.

pub use sea_orm_migration::prelude::*;

mod aurora_dsql_migrator;
mod m20220120_000001_create_post_table;
mod m20250101_000001_create_comment_table;

use aurora_dsql_migrator::AuroraDsqlMigrator;

pub struct Migrator;

#[async_trait::async_trait]
impl MigratorTrait for Migrator {
    fn migrations() -> Vec<Box<dyn MigrationTrait>> {
        vec![
            Box::new(m20220120_000001_create_post_table::Migration),
            Box::new(m20250101_000001_create_comment_table::Migration),
        ]
    }

    async fn up<'c, C>(db: C, steps: Option<u32>) -> Result<(), DbErr>
    where
        C: IntoSchemaManagerConnection<'c>,
    {
        AuroraDsqlMigrator::up::<_, Self>(db, steps).await
    }

    async fn down<'c, C>(db: C, steps: Option<u32>) -> Result<(), DbErr>
    where
        C: IntoSchemaManagerConnection<'c>,
    {
        AuroraDsqlMigrator::down::<_, Self>(db, steps).await
    }

    async fn refresh<'c, C>(db: C) -> Result<(), DbErr>
    where
        C: IntoSchemaManagerConnection<'c>,
    {
        AuroraDsqlMigrator::refresh::<_, Self>(db).await
    }

    async fn reset<'c, C>(db: C) -> Result<(), DbErr>
    where
        C: IntoSchemaManagerConnection<'c>,
    {
        AuroraDsqlMigrator::reset::<_, Self>(db).await
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment