Reputation: 24240
I unfortunately must use sql_query()
. However, I'm wondering if there is a way to serialize the database results into a nested struct
. I'd like to avoid creating a flattened data type to receive the results from the data and instead use the data struct with nested struct definitions, similar to deserializing json with #[serde(flatten)]
I've attempted this with the following code:
use diesel::*;
use serde::Deserialize;
use diesel::r2d2::{ConnectionManager, PooledConnection};
type DB = diesel::pg::Pg;
type DbConn = PooledConnection<ConnectionManager<PgConnection>>;
diesel::table! {
foo (id) {
id -> Int4,
}
}
diesel::table! {
bar (id) {
id -> Int4,
foo_id -> Int4,
}
}
#[derive(Deserialize, Queryable)]
#[diesel(table_name=foo)]
pub struct Foo {
pub id: i32,
}
#[derive(Deserialize, Queryable, QueryableByName)]
pub struct Nested {
#[sql_type = "Integer"]
pub bar_id: i32,
pub foo: Foo
}
pub fn get_nested(conn: & mut DbConn) {
sql_query("select * from bar join foo on foo.id = bar.foo_id")
.get_results::<Nested>(conn);
}
But it complains
error: Cannot determine the SQL type of foo
--> src/main.rs:30:9
|
30 | pub foo: Foo
| ^^^
|
= help: Your struct must either be annotated with `#[diesel(table_name = foo)]` or have this field annotated with `#[diesel(sql_type = ...)]`
error[E0277]: the trait bound `Untyped: load_dsl::private::CompatibleType<Nested, Pg>` is not satisfied
--> src/main.rs:35:32
|
35 | .get_results::<Nested>(conn);
| ----------- ^^^^ the trait `load_dsl::private::CompatibleType<Nested, Pg>` is not implemented for `Untyped`
| |
| required by a bound introduced by this call
|
= help: the trait `load_dsl::private::CompatibleType<U, DB>` is implemented for `Untyped`
= note: required for `SqlQuery` to implement `LoadQuery<'_, _, Nested>`
note: required by a bound in `get_results`
--> /home/rogers/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-2.0.3/src/query_dsl/mod.rs:1695:15
|
1695 | Self: LoadQuery<'query, Conn, U>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_results`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `rust_test` due to 2 previous errors
[Finished running. Exit status: 101]
Is there a way to serialize the database values into a nested structs when doing raw sql queries in diesel?
Upvotes: 0
Views: 294
Reputation: 3445
To cite from the relevant documentation:
If a field is another struct which implements
QueryableByName
, instead of a column, you can annotate that struct with#[diesel(embed)]
. Then all fields contained by that inner struct are loaded into the embedded struct.
That means that:
Foo
needs to derive QueryableByName
as wellfoo
of the Nested
struct needs to be annotated with #[diesel(embed)]
Upvotes: 2