launchbadge / sqlx

🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.
Apache License 2.0
13.32k stars 1.27k forks source link

implementation of `sqlx::Acquire` is not general enough #2016

Open szymek156 opened 2 years ago

szymek156 commented 2 years ago

I am running into an issue I am not capable to resolve by myself.

I have example code, where I want to call migrations inside the warp endpoint, using SqliteConnection:

async fn do_migration() -> Result<(), Box<dyn Error>> {
    let mut conn = SqliteConnectOptions::from_str(&format!("sqlite:///path/to/db.sqlite"))?
        .connect()
        .await?;

    sqlx::migrate!("./migrations").run(&mut conn).await?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let endpoint = warp::path("v1")
        .and(warp::path!("create_item"))
        .then(|| async move {
            do_migration().await;
        });

    Ok(())
}

Produces following error

 --> src/main.rs:24:10
   |
24 |         .then(|| async move {
   |          ^^^^ implementation of `sqlx::Acquire` is not general enough
   |
   = note: `sqlx::Acquire<'1>` would have to be implemented for the type `&'0 mut SqliteConnection`, for any two lifetimes `'0` and `'1`...
   = note: ...but `sqlx::Acquire<'2>` is actually implemented for the type `&'2 mut SqliteConnection`, for some specific lifetime `'2`

Interestingly enough when using connection pool, code compiles:

async fn do_migration_pool() -> Result<(), Box<dyn Error>> {
    let mut pool = SqlitePoolOptions::new().connect(":memory:").await?;

    sqlx::migrate!("./migrations").run(&pool).await?;

    Ok(())
}

let endpoint = warp::path("v1")
        .and(warp::path!("create_item"))
        .then(|| async move {
            do_migration_pool().await;
        });

Code to reproduce: cargo run in: https://github.com/szymek156/sqlx/tree/szymek156/migration_in_warp/examples/sqlite/migration_in_warp

I am aware of "workaround" stated here, but I don't know how to apply it in my case, nor it's even applicable.

abonander commented 2 years ago

It's an issue with the signature of Migrator::run() which I actually ran into while implementing #2001. To work around it I added .run_direct() which takes a mutable reference to a connection and doesn't use the Acquire trait. It's #[doc(hidden)] because I didn't want to commit to the naming and make it part of the stable API.