Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running Diesel migration without CLI, but using code

I'm trying to make docker image with my actix web and I need to make migration from code. I have already checked documentation and I find this:

pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();

fn run_migration(conn: &mut PgConnection) {
    conn.run_pending_migrations(MIGRATIONS).unwrap();
}

But this is not work with my database. Code run and nothing happened... No errors, no migration, nothing.

My implementation:

use diesel::{r2d2::ConnectionManager, r2d2::Pool};
use dotenvy::dotenv;
use diesel::pg::PgConnection;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use crate::schema::books;

use crate::models::{Book, NewBook};

#[derive(Clone)]
pub struct DbPoolManager {
    pub pool: Pool<ConnectionManager<PgConnection>>,
}

impl DbPoolManager {
    pub fn new() -> Self {
        dotenv().ok();
    let db_user = env::var("PG_USER")
                            .expect("PG_USER is not set");
    let db_password = env::var("PG_PASSWORD")
                            .expect("PG_PASSWORD is not set");
    let db_ip = env::var("PG_HOST")
                            .expect("PG_HOST is not set!");
    let db_name = env::var("PG_DBNAME")
                            .expect("PG_DBNAME is not set!");
    let connection_string = format!("postgres://{}:{}@{}/{}",
                                    db_user,
                                    db_password,
                                    db_ip,
                                    db_name);
    
    //let connection_string = env::var("DATABASE_URL").unwrap();
    let manager = ConnectionManager::<PgConnection>::new(connection_string);
    let pool = Pool::builder()
                       .max_size(1) // here will be more
                       .build(manager)
                       .expect("Failed to create postgress pool");
        DbPoolManager { pool }
    }

    pub fn run_migration(&self) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
        let migrations: EmbeddedMigrations = embed_migrations!("../migrations/2023-04-23-110415_create_books");
        self.pool
            .get()
            .unwrap() // here we are getting connection
            .run_pending_migrations(migrations)
            .expect("Can't run migration");
        Ok(())
    }
}

Link to documentation documentation

I was trying to find something in PgConnection documentation Here!

And I can find nothing about run_pending_migrations.

I'm using it in main.rs:

let db_pool = DbPoolManager::new();
db_pool.run_migration().unwrap();

Can you help me with this? Running migration in docker image using diesel cli is bad idea.

like image 876
RfDzDeveloper Avatar asked Oct 15 '25 16:10

RfDzDeveloper


1 Answers

I was struggling with the same issue, just found how to make it work :)

run_pending_migrations is a method in MigrationHarness trait, so the connection you're passing should implement that trait.

MigrationHarness uses a generic type DB, which has to implement the "Backend" trait, since you're using Postgres it is diesel::pg::Pg

use diesel_migrations::{EmbeddedMigrations, MigrationHarness};

const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
type DB = diesel::pg::Pg;

pub fn run_db_migrations(conn: &mut impl MigrationHarness<DB>) {
    conn.run_pending_migrations(MIGRATIONS).expect("Could not run migrations");
}

Passing your PgConnection as a mutable reference to run_db_migrations function should work

I hope it helps :)

like image 56
David Begara Avatar answered Oct 18 '25 08:10

David Begara



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!