Return 使用 Rocket 和 Diesel (Rust) 在 PostgreSQL 中创建的单条记录
Return single record created in PostgreSQL using Rocket and Diesel (Rust)
我正在尝试根据教程构建一个简单的网络应用程序:one, two and three。它们都使用略有不同的方法,并且是为所用库的旧版本编写的,因此当前的 Diesel 和 Rocket API 略有不同。我想响应 POST-请求 return 创建的记录或记录 ID。此时我只能 return list of records - list of a single record (attempts to return single record, based on Vec.first()
don't compile).
Cargo.toml:
[dependencies]
# chrono is needed with serialization/deserialisation options
chrono = { version = "0.4.10", features = ["serde"] }
diesel = { version = "1.4.3", features = ["postgres", "chrono", "network-address"] }
ipnetwork = "0.15.1"
dotenv = "0.9.0"
# Lazy static initialization
lazy_static = "1.3.0"
# Rocket Webserver
rocket = "0.4.2"
rocket_contrib = {version = "0.4.2", features = ["json", "diesel_postgres_pool"]}
# Connection pooling
r2d2 = "0.8.7"
r2d2-diesel = "1.0.0"
# Serialization/Deserialization
serde = "1.0.104"
serde_json = "1.0.44"
serde_derive = "1.0.104"
models.rs:
#![allow(proc_macro_derive_resolution_fallback)]
use crate::schema::bs_date_forecast;
use chrono::{NaiveDate, NaiveDateTime};
use ipnetwork::IpNetwork;
use diesel::prelude::*;
#[derive(Queryable, Insertable, Serialize, Deserialize)]
#[table_name="bs_date_forecast"]
pub struct BsDateForecast {
pub id: Option<i32>,
pub predicted_date: NaiveDate,
pub seer_ip: IpNetwork,
pub created_timestamp: NaiveDateTime, // Defined automatically at the database level
}
impl BsDateForecast {
// Would like to return the record (BsDateForecast) instead, but don't know how
pub fn create(forecast: BsDateForecast,
conn: &PgConnection) -> QueryResult<Vec<BsDateForecast>> {
diesel::insert_into(bs_date_forecast::table)
.values(&forecast)
.get_results(conn)
}
}
schema.rs:
table! {
bs_date_forecast (id) {
id -> Nullable<Int4>,
predicted_date -> Date,
seer_ip -> Inet,
created_timestamp -> Timestamptz,
}
}
routes.rs:
use diesel::{self, prelude::*};
use rocket_contrib::json::{Json, JsonValue};
use rocket::response::status;
use crate::models::{BsDateForecast};
use crate::schema;
use crate::DbConn;
use serde_json::Value;
#[post("/predictions", format = "application/json", data = "<prediction>")]
pub fn create(prediction: Json<BsDateForecast>, conn: DbConn) -> Json<Vec<BsDateForecast>> {
let insert = BsDateForecast{id: None, ..prediction.into_inner()};
Json(BsDateForecast::create(insert, &conn))
}
就像更改从数据库加载值的函数一样简单。
impl BsDateForecast {
// Would like to return the record (BsDateForecast) instead, but don't know how
pub fn create(forecast: BsDateForecast,
conn: &PgConnection) -> QueryResult<BsDateForecast> {
diesel::insert_into(bs_date_forecast::table)
.values(&forecast)
.get_result(conn)
}
}
有关详细信息(和其他可用方法),请参阅 RunQueryDsl
的文档
我正在尝试根据教程构建一个简单的网络应用程序:one, two and three。它们都使用略有不同的方法,并且是为所用库的旧版本编写的,因此当前的 Diesel 和 Rocket API 略有不同。我想响应 POST-请求 return 创建的记录或记录 ID。此时我只能 return list of records - list of a single record (attempts to return single record, based on Vec.first()
don't compile).
Cargo.toml:
[dependencies]
# chrono is needed with serialization/deserialisation options
chrono = { version = "0.4.10", features = ["serde"] }
diesel = { version = "1.4.3", features = ["postgres", "chrono", "network-address"] }
ipnetwork = "0.15.1"
dotenv = "0.9.0"
# Lazy static initialization
lazy_static = "1.3.0"
# Rocket Webserver
rocket = "0.4.2"
rocket_contrib = {version = "0.4.2", features = ["json", "diesel_postgres_pool"]}
# Connection pooling
r2d2 = "0.8.7"
r2d2-diesel = "1.0.0"
# Serialization/Deserialization
serde = "1.0.104"
serde_json = "1.0.44"
serde_derive = "1.0.104"
models.rs:
#![allow(proc_macro_derive_resolution_fallback)]
use crate::schema::bs_date_forecast;
use chrono::{NaiveDate, NaiveDateTime};
use ipnetwork::IpNetwork;
use diesel::prelude::*;
#[derive(Queryable, Insertable, Serialize, Deserialize)]
#[table_name="bs_date_forecast"]
pub struct BsDateForecast {
pub id: Option<i32>,
pub predicted_date: NaiveDate,
pub seer_ip: IpNetwork,
pub created_timestamp: NaiveDateTime, // Defined automatically at the database level
}
impl BsDateForecast {
// Would like to return the record (BsDateForecast) instead, but don't know how
pub fn create(forecast: BsDateForecast,
conn: &PgConnection) -> QueryResult<Vec<BsDateForecast>> {
diesel::insert_into(bs_date_forecast::table)
.values(&forecast)
.get_results(conn)
}
}
schema.rs:
table! {
bs_date_forecast (id) {
id -> Nullable<Int4>,
predicted_date -> Date,
seer_ip -> Inet,
created_timestamp -> Timestamptz,
}
}
routes.rs:
use diesel::{self, prelude::*};
use rocket_contrib::json::{Json, JsonValue};
use rocket::response::status;
use crate::models::{BsDateForecast};
use crate::schema;
use crate::DbConn;
use serde_json::Value;
#[post("/predictions", format = "application/json", data = "<prediction>")]
pub fn create(prediction: Json<BsDateForecast>, conn: DbConn) -> Json<Vec<BsDateForecast>> {
let insert = BsDateForecast{id: None, ..prediction.into_inner()};
Json(BsDateForecast::create(insert, &conn))
}
就像更改从数据库加载值的函数一样简单。
impl BsDateForecast {
// Would like to return the record (BsDateForecast) instead, but don't know how
pub fn create(forecast: BsDateForecast,
conn: &PgConnection) -> QueryResult<BsDateForecast> {
diesel::insert_into(bs_date_forecast::table)
.values(&forecast)
.get_result(conn)
}
}
有关详细信息(和其他可用方法),请参阅 RunQueryDsl
的文档