[英]Making a raw sql-query in Rust Diesel
I need to query a function in Postgresql (14) using diesel.我需要使用柴油查询 Postgresql (14) 中的 function。 I already have queries that works on tables and views.
我已经有适用于表和视图的查询。 This works, a view in this case.
这有效,在这种情况下是一个视图。
schema.rs:
table! {
latest_readings {
measurement_time_default -> Timestamptz,
id -> Integer,
data -> Jsonb,
}
}
models.rs:
#[derive(Serialize, Queryable)]
pub struct LatestReading {
#[diesel(deserialize_as = "MyDateTimeWrapper")]
pub measurement_time_default: DateTime<Local>,
pub id: i32,
pub data: serde_json::Value,
}
controller.rs:
pub async fn get_readings(db: web::Data<Pool>) -> Result<HttpResponse, Error> {
Ok(web::block(move || db_get_readings(db))
.await
.map(|reading| HttpResponse::Ok().json(reading))
.map_err(|_| HttpResponse::InternalServerError())?)
}
fn db_get_readings(pool: web::Data<Pool>) -> Result<Vec<LatestReading>, diesel::result::Error> {
let conn = pool.get().unwrap();
latest_readings.load::<LatestReading>(&conn)
}
This won't compile.这不会编译。 The part that call the postgresql-function.
调用 postgresql 函数的部分。
schema.rs:
table! {
measurements_single_location_function {
id -> Integer,
name -> Text,
latitude -> Numeric,
longitude -> Numeric,
measurement_time_default -> Timestamptz,
measurements -> Jsonb,
}
}
models.rs:
#[derive(Serialize, Queryable, QueryableByName)]
#[table_name = "measurements_single_location_function"]
pub struct MeasurementsSingleLocation {
pub id: i32,
pub name: String,
pub latitude: BigDecimal,
pub longitude: BigDecimal,
#[diesel(deserialize_as = "MyDateTimeWrapper")]
pub measurement_time_default: DateTime<Local>,
pub measurements: serde_json::Value,
}
DB-query in controllers.rs:
fn db_get_measurements_single_location(
pool: web::Data<Pool>,
location_id: i32,
rows: i32,
) -> QueryResult<Vec<MeasurementsSingleLocation>> {
let conn = pool.get().unwrap(); // Error on next line
let result: QueryResult<Vec<MeasurementsSingleLocation>> =
sql_query("select * from measurements_single_location_function(1,10)")
.load::<MeasurementsSingleLocation>(&conn);
return result;
}
The compile-error:编译错误:
Compiling weather_rest v0.1.0 (/Users/claus/devel/rust/vegvesen/weather_rest)
error[E0277]: the trait bound `SqlQuery: LoadQuery<_, MeasurementsSingleLocation>` is not satisfied
--> src/controller.rs:141:14
|
141 | .load::<MeasurementsSingleLocation>(&conn);
| ^^^^ the trait `LoadQuery<_, MeasurementsSingleLocation>` is not implemented for `SqlQuery`
|
= help: the following implementations were found:
<SqlQuery as LoadQuery<Conn, T>>
note: required by a bound in `load`
--> /Users/claus/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-1.4.6/src/query_dsl/mod.rs:1238:15
|
1238 | Self: LoadQuery<Conn, U>,
| ^^^^^^^^^^^^^^^^^^ required by this bound in `load`
I am not able to see what I am missing here.我看不到我在这里缺少的东西。
Cargo.toml:
diesel = { version = "1.4.6", features = ["postgres", "uuidv07", "r2d2", "chrono", "numeric", "serde_json"] }
I recently wrote a backend-service for another project using this excellent example as a template.我最近使用这个优秀示例作为模板为另一个项目编写了后端服务。 I applied the same structure to this and it now compiles.
我对此应用了相同的结构,现在可以编译了。
schema.rs:
table! {
measurements_single_location_function {
id -> Integer,
name -> Text,
latitude -> Text,
longitude -> Text,
measurement_time_default -> Timestamptz,
measurements -> Jsonb,
}
}
routes.rs:
#[get("/measurements_single_location/{id}/{rows}")]
async fn measurements_single_location(path: web::Path<(i32, i32)>) -> Result<HttpResponse, CustomError> {
let (id, rows) = path.into_inner();
let m = MeasurementsSingleLocation::measurements_single_location(id, rows)?;
Ok(HttpResponse::Ok().json(m))
}
pub fn init_routes(config: &mut web::ServiceConfig) {
config.service(measurements_single_location);
}
models.rs:
#[derive(Serialize, QueryableByName)]
#[table_name = "measurements_single_location_function"]
pub struct MeasurementsSingleLocation {
pub id: i32,
pub name: String,
pub latitude: String,
pub longitude: String,
pub measurement_time_default: NaiveDateTime,
pub measurements: serde_json::Value,
}
impl MeasurementsSingleLocation {
pub fn measurements_single_location(id: i32, rows: i32) -> Result<Vec<MeasurementsSingleLocation>, CustomError> {
let q = "select * from measurements_single_location_function($1,$2)";
let mut conn = db::connection()?;
let m= diesel::sql_query(q)
.bind::<Integer, _>(id)
.bind::<Integer, _>(rows)
.get_results(&mut conn)?;
Ok(m)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.