Rocket: Guide example for connection pools is misleading because it doesn't import diesel's macros

Created on 18 Mar 2019  ·  6Comments  ·  Source: SergioBenitez/Rocket

https://rocket.rs/v0.4/guide/state/#usage

#[macro_use] extern crate rocket_contrib;

use rocket_contrib::databases::diesel;

#[database("sqlite_logs")]
struct LogsDbConn(diesel::SqliteConnection);

fn main() {
    rocket::ignite()
       .attach(LogsDbConn::fairing())
       .launch();
}

instead of this

use rocket_contrib::databases::diesel;

I had to use this

  + #[macro_use]                                                                                                 
  + extern crate diesel; 

Or none of the diesel macros were available. Resulting in errors like

error: cannot find macro `joinable!` in this scope                                                               
error: cannot find macro `allow_tables_to_appear_in_same_query!` in this scope                                  
error: cannot find macro `table!` in this scope                                                                  
docs

Most helpful comment

and the example works as-is.

I guess that's the root of my issue, the example works, but the example doesn't use diesel, it just puts some diesel connections in a pool.

Maybe be a little merciful to beginners and let them know that to really use diesel you need more than what the example shows?

All 6 comments

I don't see anything obvious in the documentation about the issue, but it's been discussed a few times on IRC. The re-exports are provided primarily for convenience and a certain amount of version independence -- you can use rocket_contrib::databases::whatever without adding whatever to Cargo.toml or keeping too careful track of which version of whatever is compatible.

This works well for pretty much everything -- except diesel, because diesel depends heavily on its macros and they are pretty much unusable without #[macro_use]. This will be alleviated in diesel-rs/diesel#1956, but it will likely be more convenient to keep using #[macro_use] anyway, at least for a while.

Note that only the crate that uses diesel's macros (e.g. for schema.rs) needs #[macro_use] - if the rocket server is in a separate crate from the database code, the #[macro_use] is unnecessary in the server crate and the example works as-is.


Anyway, I'm not really sure about how best to change the example in question. extern crate diesel; is only needed for diesel so I wouldn't want to add it. On the other hand I think it's just about the most popular way to access databases right now, and it ought to be represented well in the examples.

and the example works as-is.

I guess that's the root of my issue, the example works, but the example doesn't use diesel, it just puts some diesel connections in a pool.

Maybe be a little merciful to beginners and let them know that to really use diesel you need more than what the example shows?

As a total beginner I would prefer to see examples that immediately get me up and running. A comment in the example that says ”diesel depends heavily on its macros this will be alleviated in diesel-rs/diesel#1956” let's beginners know that it's not the ideal end state.

For anyone else coming here from google, the solution to errors like

error: cannot find macro `table!` in this scope
 --> src/schema.rs:1:1
  |
1 | table! {
  | ^^^^^

error: cannot find macro `joinable!` in this scope
  --> src/schema.rs:98:1
   |
98 | joinable!(EnumValue -> EnumKind (category_id));
   | ^^^^^^^^

error: cannot find macro `allow_tables_to_appear_in_same_query!` in this scope
   --> src/schema.rs:108:1
    |
108 | allow_tables_to_appear_in_same_query!(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: cannot find derive macro `Queryable` in this scope
 --> src/models.rs:1:10
  |
1 | #[derive(Queryable)]
  |          ^^^^^^^^^

or perhaps these errors, which occur when you don't quite understand how rust imports work:

error[E0254]: the name `diesel` is defined multiple times
 --> src/main.rs:7:5
  |
5 | #[macro_use] extern crate diesel;
  |              -------------------- previous import of the extern crate `diesel` here
6 | 
7 | use rocket_contrib::databases::diesel;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `diesel` reimported here
  |
  = note: `diesel` must be defined only once in the type namespace of this module

is to follow the instructions in the top-level bug report.

I case anyone needs some guide... I've found this:
https://cprimozic.net/blog/rust-rocket-cloud-run/

I'm working through it right now.
I stumbled upon the same problems, trying to figure out how to do a simple query.

If I'm reading these right, I think most of the issues with the guide can be addressed by expanding the example to something like this:


[dependencies]
diesel = "1.4"

[dependencies.rocket_contrib]
version = "0.4.2"
default-features = false
features = ["diesel_sqlite_pool", "redis_pool"]
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate diesel;

// diesel schema
mod schema;
use schema::logs;

// By using redis re-exported from rocket_contrib, we don't need to put redis
// in Cargo.toml and we are guaranteed to use the version of redis that is
// compatible with rocket_contrib.
use rocket_contrib::databases::redis;

#[database("sqlite_logs")]
struct LogsDbConn(diesel::SqliteConnection);

// Multiple databases can be created of the same or different connection types.
#[database("redis_db")]
struct RedisConn(redis::Connection)

#[get("/logs/<id>")]
fn get_logs(conn: LogsDbConn, id: usize) -> diesel::result::QueryResult<Logs> {
    logs::filter(id.eq(log_id)).load(&*conn)
}

#[get("/redis/<id>")]
fn get_redis_value(conn: RedisConn, id: usize) -> Result<String, redis::RedisError> {
    conn.get(id)
}

fn main() {
    rocket::ignite()
        .attach(LogsDbConn::fairing())
        .mount("/", routes![get_logs, get_redis_value])
        .launch();
}

See the [todo example] for a more complete application, or the [rocket_contrib::databases] API docs for more details of rocket's database connectivity.

Was this page helpful?
0 / 5 - 0 ratings