Zum Hauptinhalt springen

πŸ”„ Schema Migrations Management

As production systems evolve, database schemas require incremental versioning without downtime. ferrox-migrations provides automated schema migrations runner for relational and document databases.


1. Migration File Structure​

Migrations are organized chronologically with up/down SQL or Rust migration steps:

migrations/
β”œβ”€β”€ m20260101_000001_create_users_table.rs
β”œβ”€β”€ m20260201_000002_add_roles_to_users.rs
└── mod.rs

2. Defining a SeaORM Migration​

use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(Users::Table)
.if_not_exists()
.col(
ColumnDef::new(Users::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(Users::Username).string().not_null())
.col(ColumnDef::new(Users::Email).string().not_null())
.to_owned(),
)
.await
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Users::Table).to_owned())
.await
}
}

#[derive(DeriveIden)]
enum Users {
Table,
Id,
Username,
Email,
}

3. Running Migrations Programmatically​

Execute pending migrations automatically on startup during main.rs bootstrap:

use sea_orm_migration::prelude::*;
use ferrox_migrations::Migrator;

pub async fn run_migrations(db: &DatabaseConnection) -> Result<(), AppError> {
println!("πŸ”„ Running database migrations...");
Migrator::up(db, None)
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
println!("βœ… Database schema up-to-date!");
Ok(())
}

4. βœ… Best Practices​

  • Never modify published migrations: Always create new migration files for schema changes to ensure CI/CD repeatability across environments.