Как запустить миграцию дизеля с Rocket на производстве? - PullRequest
0 голосов
/ 05 апреля 2020

Мне нужно запустить миграцию базы данных Diesel на производстве для приложения на базе Rocket. Как правило, существуют способы выполнения миграции базы данных:

  1. При запуске приложения.
  2. Отдельно от запуска приложения.

Я предпочитаю второй вариант это будет вызвано использованием флага --migrate для двоичного файла приложения, но, поскольку целевое приложение достаточно простое, первый способ будет работать хорошо.

В системе отслеживания проблем Diesel есть поток о запуске миграций в рабочей среде и рекомендации о том, как это сделать:

  1. Добавьте diesel_migrations к вашим зависимостям
  2. Включите extern crate diesel_migrations в вашу корзину, и убедитесь, что вы украсили его #[macro_use]
  3. . В начале вашего кода добавьте embed_migrations!()
  4. . Для запуска миграции используйте embedded_migrations::run(&db_conn)
* 1031. *

В main.rs я сделал:

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;

#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_contrib;

#[database("my_db_name")]
pub struct DbConn(diesel::PgConnection);

fn main() {
    // Update database
    embed_migrations!();
    embedded_migrations::run(&DbConn);
    // Launch the app
    ...
}

Это приводит к ошибке:

error[E0277]: the trait bound `fn(diesel::r2d2::PooledConnection<<diesel::PgConnection as rocket_contrib::databases::Poolable>::Manager>) -> DbConn {DbConn}: diesel::Connection` is not satisfied
  --> src/main.rs:30:30
   |
29 |     embed_migrations!();
   |     --------------------
   |     |
   |     required by this bound in `main::embedded_migrations::run`
30 |     embedded_migrations::run(&DbConn);
   |                              ^^^^^^^ the trait `diesel::Connection` is not implemented for `fn(diesel::r2d2::PooledConnection<<diesel::PgConnection as rocket_contrib::databases::Poolable>::Manager>) -> DbConn {DbConn}`
   |
   = note: required because of the requirements on the impl of `diesel_migrations::MigrationConnection` for `fn(diesel::r2d2::PooledConnection<<diesel::PgConnection as rocket_contrib::databases::Poolable>::Manager>) -> DbConn {DbConn}`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

Как это исправить?

1 Ответ

1 голос
/ 06 апреля 2020

Погуглил еще немного и нашел рабочий пример здесь .

Код ключа

use rocket::Rocket;
use rocket::fairing::AdHoc;

// This macro from `diesel_migrations` defines an `embedded_migrations` module
// containing a function named `run`. This allows the example to be run and
// tested without any outside setup of the database.
embed_migrations!();

#[database("sqlite_database")]
pub struct DbConn(SqliteConnection);

fn run_db_migrations(rocket: Rocket) -> Result<Rocket, Rocket> {
    let conn = DbConn::get_one(&rocket).expect("database connection");
    match embedded_migrations::run(&*conn) {
        Ok(()) => Ok(rocket),
        Err(e) => {
            error!("Failed to run database migrations: {:?}", e);
            Err(rocket)
        }
    }
}

fn rocket() -> Rocket {
    rocket::ignite()
        .attach(DbConn::fairing())
        .attach(AdHoc::on_attach("Database Migrations", run_db_migrations))
        .mount("/", StaticFiles::from("static/"))
        .mount("/", routes![index])
        .mount("/todo", routes![new, toggle, delete])
        .attach(Template::fairing())
}
...