我需要在基于 Rocket 的应用程序中的生产环境中运行 Diesel 数据库迁移。通常有两种方法可以执行数据库迁移:
- 在应用程序启动时。
- 与应用程序启动分开。
我更喜欢第二种选项,即通过使用应用程序二进制文件的 --migrate
标志来调用,但由于目标应用程序相当简单,第一种方式也可以胜任。
在 Diesel 问题跟踪器中有一个关于在生产环境中运行迁移的线程,并提供了如何执行迁移的建议:
- 将
diesel_migrations
添加到您的依赖项中- 在您的 crate 中包含
extern crate diesel_migrations
,并确保用#[macro_use]
进行修饰- 在代码开头添加
embed_migrations!()
- 要运行迁移,请使用
embedded_migrations::run(&db_conn)
在 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)
如何解决这个问题?
run
函数,例如:let db_conn = whatever; embedded_migrations::run(&db_conn);
。 - JmbConnection
的实例,因此,请根据 rocket 文档(因为我在那里看到了他们神奇的宏)建议执行任何操作,或者只需在应用程序启动时建立一个新的PgConnection
来运行迁移。 - weiznich