Expand description
§prax-migrate
Migration engine for the Prax ORM.
This crate provides functionality for:
- Schema diffing between Prax schema definitions and database state
- SQL migration generation for PostgreSQL (with MySQL/SQLite planned)
- Migration file management on the filesystem
- Migration history tracking in the database
- Safe, transactional migration application and rollback
- Resolution system for handling migration conflicts and checksums
§Architecture
The migration engine compares your Prax schema definition with the current
database state and generates SQL scripts to bring the database up to date.
It tracks applied migrations in a _prax_migrations table.
┌──────────────┐ ┌────────────────┐ ┌─────────────┐
│ Prax Schema │────▶│ Schema Differ │────▶│ SQL Gen │
└──────────────┘ └────────────────┘ └─────────────┘
│ │
▼ ▼
┌────────────────┐ ┌─────────────┐
│ Migration Plan │────▶│ Apply SQL │
└────────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ History Tbl │
└─────────────┘§Example
ⓘ
use prax_migrate::{MigrationConfig, MigrationEngine};
async fn run_migrations() -> Result<(), Box<dyn std::error::Error>> {
// Parse your schema
let schema = prax_schema::parse_schema(r#"
model User {
id Int @id @auto
email String @unique
name String?
}
"#)?;
// Configure migrations
let config = MigrationConfig::new()
.migrations_dir("./migrations");
// Create engine with your history repository
let history = /* your history implementation */;
let engine = MigrationEngine::new(config, history);
// Initialize (creates migrations table)
engine.initialize().await?;
// Plan migrations
let plan = engine.plan(&schema).await?;
println!("Plan: {}", plan.summary());
// Apply migrations
let result = engine.migrate().await?;
println!("Applied {} migrations in {}ms",
result.applied_count, result.duration_ms);
Ok(())
}§Migration Files
Migrations are stored as directories with up.sql and down.sql files:
migrations/
├── 20231215120000_create_users/
│ ├── up.sql
│ └── down.sql
├── 20231216090000_add_posts/
│ ├── up.sql
│ └── down.sql
└── resolutions.toml # Migration resolutions§Resolution System
The resolution system handles common migration issues:
- Checksum Mismatches: When a migration is modified after being applied
- Skipped Migrations: Intentionally skip migrations (e.g., legacy tables)
- Baseline Migrations: Mark migrations as applied without running them
- Renamed Migrations: Map old migration IDs to new ones
- Conflict Resolution: Handle conflicts between migrations
ⓘ
use prax_migrate::{Resolution, ResolutionConfig};
let mut resolutions = ResolutionConfig::new();
// Accept a checksum change
resolutions.add(Resolution::accept_checksum(
"20240101_create_users",
"old_checksum",
"new_checksum",
"Fixed column type",
));
// Skip a migration
resolutions.add(Resolution::skip(
"20240102_legacy_table",
"Already exists in production",
));
// Mark as baseline (applied without running)
resolutions.add(Resolution::baseline(
"20240103_initial",
"Database was imported from backup",
));
// Save to file
resolutions.save("migrations/resolutions.toml").await?;Re-exports§
pub use diff::EnumAlterDiff;pub use diff::EnumDiff;pub use diff::FieldAlterDiff;pub use diff::FieldDiff;pub use diff::IndexDiff;pub use diff::ModelAlterDiff;pub use diff::ModelDiff;pub use diff::SchemaDiff;pub use diff::SchemaDiffer;pub use diff::UniqueConstraint;pub use engine::MigrationConfig;pub use engine::MigrationEngine;pub use engine::MigrationPlan;pub use engine::MigrationResult;pub use engine::MigrationStatus;pub use error::MigrateResult;pub use error::MigrationError;pub use file::MigrationFile;pub use file::MigrationFileManager;pub use history::MigrationHistoryRepository;pub use history::MigrationLock;pub use history::MigrationRecord;pub use introspect::ColumnInfo;pub use introspect::ConstraintInfo;pub use introspect::EnumInfo;pub use introspect::IndexInfo;pub use introspect::IntrospectionConfig;pub use introspect::IntrospectionResult;pub use introspect::Introspector;pub use introspect::SchemaBuilder;pub use introspect::SkippedTable;pub use introspect::TableInfo;pub use resolution::ConflictStrategy;pub use resolution::Resolution;pub use resolution::ResolutionAction;pub use resolution::ResolutionBuilder;pub use resolution::ResolutionConfig;pub use resolution::ResolutionCounts;pub use resolution::ResolutionWarning;pub use shadow::FieldDrift;pub use shadow::IndexDrift;pub use shadow::SchemaDrift;pub use shadow::ShadowConfig;pub use shadow::ShadowDatabase;pub use shadow::ShadowDatabaseManager;pub use shadow::ShadowDiffResult;pub use shadow::ShadowState;pub use shadow::detect_drift;pub use procedure::ChangeType;pub use procedure::ParameterMode;pub use procedure::ParallelSafety;pub use procedure::ProcedureAlterDiff;pub use procedure::ProcedureChange;pub use procedure::ProcedureDefinition;pub use procedure::ProcedureDiff;pub use procedure::ProcedureDiffer;pub use procedure::ProcedureHistoryEntry;pub use procedure::ProcedureLanguage;pub use procedure::ProcedureParameter;pub use procedure::ProcedureSqlGenerator;pub use procedure::ProcedureStore;pub use procedure::ReturnColumn;pub use procedure::Volatility;pub use procedure::TriggerAlterDiff;pub use procedure::TriggerDefinition;pub use procedure::TriggerEvent;pub use procedure::TriggerLevel;pub use procedure::TriggerTiming;pub use procedure::EventAlterDiff;pub use procedure::EventDiff;pub use procedure::EventInterval;pub use procedure::EventSchedule;pub use procedure::IntervalUnit;pub use procedure::OnCompletion;pub use procedure::ScheduledEvent;pub use procedure::JobSchedule;pub use procedure::JobStep;pub use procedure::NotifyLevel;pub use procedure::ScheduleFrequency;pub use procedure::SqlAgentJob;pub use procedure::StepAction;pub use procedure::StepType;pub use procedure::Weekday;pub use procedure::AtlasOperation;pub use procedure::AtlasTrigger;pub use procedure::AtlasTriggerType;pub use procedure::AuthOperation;pub use sql::MigrationSql;pub use sql::PostgresSqlGenerator;
Modules§
- diff
- Schema diffing for generating migrations.
- engine
- Migration engine implementation.
- error
- Error types for the migration engine.
- file
- Migration file management.
- history
- Migration history tracking.
- introspect
- Database introspection for reverse-engineering schemas.
- procedure
- Procedure migrations - Version control for stored procedures, functions, and triggers.
- resolution
- Migration resolution system.
- shadow
- Shadow database support for safe migration testing.
- sql
- SQL generation for migrations.