Database Migrations in Rust: Overview of Tools and Libraries

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Database Migrations in Rust: Overview of Tools and Libraries



When developing any application, sooner or later the need arises to change the database structure. Adding new columns, creating indexes, or renaming tables — all of this requires careful schema version management. In the Rust ecosystem, there are several mature solutions for performing migrations. In this article, we will review the main approaches and libraries available for database schema management tasks.



Why are migrations needed?

Migrations allow you to:

  • Version changes — each migration is a separate file with a version number.
  • Automate deployment — apply and roll back changes during deployment.
  • Work in a team — all developers synchronize the schema locally.
  • Avoid errors — migrations protect against accidental data modification.


Main tools for migrations in Rust



1. Diesel Migration (built into Diesel ORM)

Diesel is the most popular ORM for Rust. It provides a built-in migration engine via the diesel_cli CLI utility.

Key features:

  • Generation of migration files with SQL queries.
  • Support for PostgreSQL, MySQL, SQLite.
  • Commands: migration generate, migration run, migration redo.
  • Automatic tracking of applied migrations.

Example of creating and applying a migration:

# Install CLIcargo install diesel_cli --no-default-features --features postgres

# Create a new migrationdiesel migration generate create_users

# Two SQL files will appear in the migrations/ folder:# up.sql — code to apply# down.sql — code to roll back

# Run the migrationdiesel migration run

Contents of up.sql:

CREATE TABLE users (    id SERIAL PRIMARY KEY,    name VARCHAR(255) NOT NULL,    email VARCHAR(255) UNIQUE NOT NULL,    created_at TIMESTAMP DEFAULT NOW());

down.sql:

DROP TABLE IF EXISTS users;


2. SQLx migrate (part of the SQLx ecosystem)

SQLx is an async SQL database driver. Its migration subsystem works without an ORM, using only plain SQL scripts.

Distinctive features:

  • Support for PostgreSQL, MySQL, SQLite, MSSQL.
  • Integration with CLI and programmatic execution from code.
  • Ability to use Rust code for checks before migration.
  • Automatic integrity verification (file hashing).

Example of programmatic migration execution in Rust:

use sqlx::migrate::Migrator;use sqlx::PgPool;

#[tokio::main]async fn main() -> Result<(), sqlx::Error> { let pool = PgPool::connect("postgres://user:pass@localhost/db").await?; // Specify the path to the migrations folder let migrator = Migrator::new(std::path::Path::new("./migrations")).await?; // Run all pending migrations migrator.run(&pool).await?; println!("Migrations completed successfully!"); Ok(())}

Structure of the migrations/ folder:

migrations/├── 20231001_initial.sql├── 20231002_add_email_index.sql└── 20231003_create_roles.sql

Each file contains plain SQL, for example:

-- 20231001_initial.sqlCREATE TABLE IF NOT EXISTS users (    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),    username TEXT NOT NULL UNIQUE);


3. SeaORM Migrator (part of SeaORM)

SeaORM is a modern async ORM that offers its own migration system, SeaORM Migrator. It allows you to write migrations in Rust rather than SQL, which d

Recommendations