sqlx
sqlx copied to clipboard
Macros don't seem to work with AnyPool
Instantiate yourself an AnyPool (in my case with a Sqlite connection),
pub async fn init_data_pool() -> Result<AnyPool, io::Error> {
Ok(AnyPoolOptions::new()
.max_connections(10)
.connect("sqlite://dev.sqlite3")
.await
.map_err(|e| {
error!("Encountered error trying to make database pool: {}", e);
Error::new(io::ErrorKind::ConnectionAborted, e)
})?)
}
Now you have your pool, but it's really an AnyPool.
Let's give it a query:
#[some_async_main]
async fn main() -> io::Result<()> {
let pool = init_data_pool().await?;
give_me_data(pool.clone()).await;
}
struct SomeResult {
id: i64,
data: i64,
}
async fn give_me_data(pool: AnyPool) {
// this works as expected
sqlx::query("SELECT id, data FROM some_table")
.fetch(&pool).await.unwrap();
// this throws a compile error
sqlx::query!("SELECT id, data FROM some_table")
.fetch(&pool).await.unwrap();
}
The first query behaves as expected. The second one throws a compile error where sqlx seems to be a little too aware of what the AnyPool really is:
|
85 | .fetch(conn);
| ^^^^^ expected struct `sqlx::Any`, found struct `sqlx::Sqlite`
I've tried manually getting a connection from the pool, making it a mutable reference, making it not a reference (but also mutable), and it all seems to throw the same compile error. This isn't a problem with the non-macro version of query, so I assume this is a bug.
Supporting info
$ rustc --version
rustc 1.49.0 (e1884a8e3 2020-12-29)
sqlx version:
sqlx = { version = "0.4.2", features = ["runtime-actix-rustls", "any", "sqlite", "macros"], default-features = false }
Yeah, the macros emit instances of query::Map that are specifically keyed to the same database they compiled against. I think this is a really important sanity check and I'm loathe to drop it by default.
However, we are discussing a way to configure the macros in #916 and #121, and I think this would be a good configuration option to add, something like use_any_db: bool. @mehcode?
Alternatively we could support a protocol like sqlite+anydb:// in database URLs that would cause the macros to emit DB = Any instead of DB = Sqlite where applicable. I'm not sure which I prefer.
After discussing on Discord, @mehcode and I decided we'll support both options:
sqlx::macros!(driver = "any")which can also be used to enforce, e.g.sqlx::macros!(driver = "postgres")(will error ifDATABASE_URL=mysql://..), etc.DATABASE_URL=any+<postgresql | mysql | sqlite | ...>://.., the logic being thatany+is easier to prepend and strip off later than it is to insert and remove+any
I didn't expect a response so fast!
Thanks a bunch everyone. I look forward to it being in 0.5 😃
This is a problem we've known about for a while but weren't quite sure how to address. In the context of other ongoing discussions the sqlx::macros!(driver = "any") solution was rather obvious at least.
Hi, I've a follow up question related to this issue. I'm writing a web application which should be able to support multiple database backends, one at a time, defined by the user / admin via a configuration file. I thought Any would be the best way to go on the one hand. On the other hand I like the concept of compile time checks done by the query macros. That's why today I crossed the issue described here.
I already experimented with Offline and sqlx-cli. That works like a charm! Anyway I'm wondering if as soon as the query macros allow to use Any I'm good to go or if I rely on a fundamental misunderstanding reaching beyond the ability of query macros to work with Any.
Thanks for your support.
What is the status on this issue? Doesn't seem like it is in the milestone for next major version.
EDIT: sorry, confused the issue with something else.
Is there any status on this? It's been a while.
Is there any status on this? It's been a while.
Is there any status on this? It's been a while.
I'd just use the "unsafe" version and skip the macro. That's what I ended up doing, and probably better to do than wait another three years.
@DarrienG can you show an example? Thanks!
Is there any status on this? It's been a while.
I'd just use the "unsafe" version and skip the macro. That's what I ended up doing, and probably better to do than wait another three years.
@DarrienG can you show an example? Thanks!
Is there any status on this? It's been a while.
I'd just use the "unsafe" version and skip the macro. That's what I ended up doing, and probably better to do than wait another three years.
Look at the issue I wrote 3 years ago. There's an example that works, and one that throws a compile error. The one that works is the "unsafe" one
After discussing on Discord, @mehcode and I decided we'll support both options:
* `sqlx::macros!(driver = "any")` which can also be used to enforce, e.g. `sqlx::macros!(driver = "postgres")` (will error if `DATABASE_URL=mysql://..`), etc. * `DATABASE_URL=any+<postgresql | mysql | sqlite | ...>://..`, the logic being that `any+` is easier to prepend and strip off later than it is to insert and remove `+any`
Is this still planned?