#sqlx #sqlx-migrations #rust-migrations


Migrator for writing sqlx migration using Rust instead of SQL

17 releases (8 breaking)

0.9.2 Aug 4, 2023
0.9.1 Jul 18, 2023
0.8.0 Jul 5, 2023
0.5.0 Mar 24, 2023
0.1.0 May 28, 2022

#211 in Database interfaces

Download history 23/week @ 2023-06-09 22/week @ 2023-06-16 4/week @ 2023-06-23 57/week @ 2023-06-30 120/week @ 2023-07-07 210/week @ 2023-07-14 141/week @ 2023-07-21 47/week @ 2023-07-28 61/week @ 2023-08-04 15/week @ 2023-08-11 70/week @ 2023-08-18 35/week @ 2023-08-25 73/week @ 2023-09-08 38/week @ 2023-09-15 20/week @ 2023-09-22

131 downloads per month

MIT license

1.5K SLoC

SQLX migrator

Migrator library for writing sqlx migration using Rust instead of SQL

License Crates Version Docs
License: MIT Crate Docs

Supported Databases:

  • PostgreSQL
  • SQLite
  • MySql
  • Any


To use sqlx migrator you can configure Cargo.toml as shown below according to your requirements

sqlx_migrator = { version = "0.9.2", features=["postgres"] }


sqlx_migrator = { version = "0.9.2", features=["mysql"] }


sqlx_migrator = { version = "0.9.2", features=["sqlite"] }


sqlx_migrator = { version = "0.9.2", features=[
    # Plus any one of above database driver
    ] }


To use sqlx_migrator first you need to implement Operation trait to write your sqlx operation below are examples for using postgres based migration

use sqlx_migrator::error::Error;
use sqlx_migrator::operation::Operation;
// Its better to use sqlx imported from sqlx_migrator
use sqlx_migrator::sqlx;

pub(crate) struct FirstOperation;

impl Operation<sqlx::Postgres> for FirstOperation {
    // Up function runs apply migration
    async fn up(&self, connection: &mut sqlx::PgConnection) -> Result<(), Error> {
        sqlx::query("CREATE TABLE sample (id INTEGER PRIMARY KEY, name TEXT)")

    // down migration runs down migration
    async fn down(&self, connection: &mut sqlx::PgConnection) -> Result<(), Error> {
        sqlx::query("DROP TABLE sample").execute(connection).await?;

After creation of operation you can implement Migration struct to create single migration

use sqlx_migrator::error::Error;
use sqlx_migrator::migration::Migration;
use sqlx_migrator::operation::Operation;
use sqlx_migrator::sqlx;

pub(crate) struct FirstMigration;

impl Migration<sqlx::Postgres> for FirstMigration {
    // app where migration lies can be any value
    fn app(&self) -> &str {

    // name of migration
    // Combination of migration app and name must be unique to work properly
    fn name(&self) -> &str {

    // use parents function to add parents of a migrations.
    fn parents(&self) -> Vec<Box<dyn Migration<DB>>> {

    // use operations function to add operation part of migration
    fn operations(&self) -> Vec<Box<dyn Operation<sqlx::Postgres>>> {

    // Migration trait also have multiple other function see docs for usage

Now at last you need to create migrator for your database to run migrations

use sqlx_migrator::migrator::{Info, Migrate, Migrator};
use sqlx_migrator::sqlx::Postgres;

async fn main() {
    let uri = std::env::var("DATABASE_URL").unwrap();
    let pool = sqlx::Pool::<Postgres>::connect(&uri).await.unwrap();
    let mut migrator = Migrator::default();

Now you can use two ways to run migrator either directly running migration or creating cli from migrator For directly run

// use apply all to apply all pending migration
// or use revert all to revert all applied migrations

Or you can create cli

sqlx_migrator::cli::run(Box::new(migrator), &pool).await.unwrap();

Migrate from sqlx default sql based migration

To migrate from sqlx sql based migration you have two alternative:

  1. Write all sql migration as rust operation
  2. Write single rust based operation which apply and revert all sqlx sql based migration

Option: 1

Can be easily applied by following above usage docs where you only need to write your sql based migration as sqlx query Then you can create cli for migrator

sqlx_migrator::cli::run(Box::new(migrator), &pool).await.unwrap();

and run fake apply cli command <COMMAND_NAME> apply --fake which actually doesn't apply migration query but only update migration table

Option: 2

To run all sqlx sql based migration as single command create new operation

use sqlx_migrator::error::Error;
use sqlx_migrator::operation::Operation;
use sqlx_migrator::sqlx;

pub(crate) struct SqlxOperation;

impl Operation<sqlx::Postgres> for SqlxOperation {
    async fn up(&self, connection: &mut sqlx::PgConnection) -> Result<(), Error> {

    async fn down(&self, connection: &mut sqlx::PgConnection) -> Result<(), Error> {
        sqlx::migrate!("migrations").undo(connection, 0).await?;


~395K SLoC