[英]Rust Diesel, error loading results of a sql_query that select columns from multiple tables
I tried to execute an sql_query with Diesel that doesn't match a single table and I got the following error:我尝试使用与单个表不匹配的 Diesel 执行 sql_query,但出现以下错误:
error[E0277]: the trait bound `Untyped: load_dsl::private::CompatibleType<TimeCountSumaryEntry, _>` is not satisfied
--> src/api/cra_service.rs:263:10
|
263 | .load::<TimeCountSumaryEntry>(connection)
| ^^^^ the trait `load_dsl::private::CompatibleType<TimeCountSumaryEntry, _>` is not implemented for `Untyped`
|
= help: the trait `load_dsl::private::CompatibleType<U, DB>` is implemented for `Untyped`
= note: required because of the requirements on the impl of `LoadQuery<'_, _, TimeCountSumaryEntry>` for `SqlQuery`
note: required by a bound in `diesel::RunQueryDsl::load
Here is the relevant code (where clauses are fixed to simplify experimentations):以下是相关代码(固定 where 子句以简化实验):
#[derive(QueryableByName, Debug)]
struct TimeCountSumaryEntry {
#[diesel(sql_type = Integer)]
month: i32,
#[diesel(sql_type = Integer)]
year: i32,
#[diesel(sql_type = Integer)]
project_id: i32,
#[diesel(sql_type = Text)]
project_code: String,
#[diesel(sql_type = Double)]
time_spent: f32,
#[diesel(sql_type = Text)]
fullname: String,
}
fn _timecount_by_filters(
user_id: Option<i32>,
month: Option<u8>,
year: Option<u16>,
connection: &mut PgConnection,
) {
let query =
"SELECT
EXTRACT(MONTH FROM tc.date_assigned) as \"month\",
EXTRACT(YEAR FROM tc.date_assigned) as \"year\",
tc.project_id as project_id,
p.project_code as project_code,
sum(tc.time_spent) as time_spent,
u.lastname || ' ' || u.firstname as fullname
FROM
time_count tc
JOIN cra c on tc.cra_id = c.cra_id
JOIN project p on p.project_id = tc.project_id
JOIN \"user\" u on u.user_id = c.user_id
WHERE
u.user_id = 3
and EXTRACT(MONTH FROM tc.date_assigned) = 8
and EXTRACT(YEAR FROM tc.date_assigned) = 2022
GROUP BY
tc.project_id, u.lastname, u.firstname, \"month\", \"year\", p.project_code
ORDER BY
\"year\", \"month\", u.lastname, u.firstname, tc.project_id";
let time_counts_sumary = diesel::dsl::sql_query(query)
.load::<TimeCountSumaryEntry>(connection)
.expect("Error getting cra ids");
println!("{:?}", time_counts_sumary);
}
I can't find any resource that mention how to deal with this use case (or even that this isn't possible at all).我找不到任何提及如何处理此用例的资源(甚至根本不可能)。 I first tried with the query builder, but it didn't seem possible, so I thought sql_query the way to get those data from DB (postgresql) without getting useless information in the process, but maybe there is a better one.我第一次尝试使用查询生成器,但似乎不可能,所以我认为 sql_query 是从数据库(postgresql)获取这些数据的方法,而不会在过程中获得无用的信息,但也许有更好的方法。
Does anyone have encountered this use case or have any hints about how to deal with it?有没有人遇到过这个用例或有任何关于如何处理它的提示?
If someone have the same problem, I found where it was.如果有人有同样的问题,我找到了它的位置。
Diesel couldn't match types it got from sql_query
and what I mentioned in TimeCountSumaryEntry
. Diesel 无法匹配从sql_query
获得的类型以及我在TimeCountSumaryEntry
中提到的类型。
First here:首先在这里:
#[diesel(sql_type = Double)]
time_spent: f32,
I mistyped the Double
(it should be f64
)我打错了Double
(应该是f64
)
And second the EXTRACT()
function return a numeric in postgresql .第二个EXTRACT()
function 在 postgresql 返回一个数字。 I could use the numeric diesel feature , but in my case (year and month), an Integer is enough.我可以使用数字柴油功能,但就我而言(年和月),Integer 就足够了。 So I must specify the type in the request with CAST()
.所以我必须用CAST()
指定请求中的类型。 Like this:像这样:
CAST(EXTRACT(MONTH FROM tc.date_assigned) as Integer) as "month",
CAST(EXTRACT(YEAR FROM tc.date_assigned) as Integer) as "year",
Here is the working code:这是工作代码:
#[derive(QueryableByName, Debug)]
struct TimeCountSumaryEntry {
#[diesel(sql_type = Integer)]
month: i32,
#[diesel(sql_type = Integer)]
year: i32,
#[diesel(sql_type = Integer)]
project_id: i32,
#[diesel(sql_type = Text)]
project_code: String,
#[diesel(sql_type = Double)]
time_spent: f64,
#[diesel(sql_type = Text)]
fullname: String,
}
fn _timecount_by_filters(
user_id: Option<i32>,
month: Option<u8>,
year: Option<u16>,
connection: &mut PgConnection,
) {
let query =
"SELECT
CAST(EXTRACT(MONTH FROM tc.date_assigned) as integer) as \"month\",
CAST(EXTRACT(YEAR FROM tc.date_assigned) as integer) as \"year\",
tc.project_id as project_id,
p.project_code as project_code,
sum(tc.time_spent) as time_spent,
u.lastname || ' ' || u.firstname as fullname
FROM
time_count tc
JOIN cra c on tc.cra_id = c.cra_id
JOIN project p on p.project_id = tc.project_id
JOIN \"user\" u on u.user_id = c.user_id
WHERE
u.user_id = 3
and EXTRACT(MONTH FROM tc.date_assigned) = 8
and EXTRACT(YEAR FROM tc.date_assigned) = 2022
GROUP BY
tc.project_id, u.lastname, u.firstname, \"month\", \"year\", p.project_code
ORDER BY
\"year\", \"month\", u.lastname, u.firstname, tc.project_id";
let time_counts_sumary = diesel::dsl::sql_query(query)
.load::<TimeCountSumaryEntry>(connection)
.expect("Error getting cra ids");
println!("{:?}", time_counts_sumary);
}
I found it while trying again to this query with the query builder.我在使用查询生成器再次尝试此查询时发现了它。
I may succeed to get it work that way, I'll edit this answer when it'll be done.我可能会成功让它以这种方式工作,我会在完成后编辑这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.