您将如何为 Postgres Jsonb 类型设置 FromSql 和 ToSql 的 impl 函数,它可以是数据数组
How would you setup the impl functions of FromSql and ToSql for a Postgres Jsonb type, that can be an array of data
您将如何为 Postgres Jsonb 类型设置 FromSql 和 ToSql 的 impl 函数,它可以是数据数组。
下面是一些示例数组 json 数据。
[
{
"title": "some text",
"date_str": null,
},
{
"title": "some more text",
"date_str": "Feb 25th",
},
]
这是我目前拥有的代码。我能够毫无问题地找出 none 数组实现,但我正在努力为包装类型 (Vec) 创建 ToSql 和 FromSql。我收到错误“Error(DeserializationError(error("invalid type: map, expaected a sequence", line: 0, column: 0)))”,我不确定我需要做什么更改。
// models.rs
#[derive(Debug, Serialize, Deserialize, Queryable, QueryableByName)]
#[table_name = "table"]
pub struct table {
pub id: i32,
pub cust_jsonb: CustJsonbs,
}
#[derive(FromSqlRow, AsExpression, Debug, Serialize, Deserialize)]
#[sql_type = "Jsonb"]
pub struct CustJsonb {
pub title: String,
pub date_arg: Option<String>,
}
//wrapper type
#[derive(FromSqlRow, AsExpression, Debug, Serialize, Deserialize)]
#[sql_type = "Jsonb"]
pub struct CustJsonbs (
Vec<CustJsonb>
);
// None array implementation that works
impl FromSql<Jsonb, Pg> for CustJsonb {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, Pg> for CustJsonb {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> diesel::serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as ToSql<Jsonb, Pg>>::to_sql(&value, out)
}
}
// Array implementation - I've tried (doesn't work and not sure how to fix it exactly)
impl FromSql<Jsonb, Pg> for CustJsonbs {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, Pg> for CustJsonbs {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> diesel::serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as ToSql<Jsonb, Pg>>::to_sql(&value, out)
}
}
所以这个问题的答案很简单。
impl FromSql<Jsonb, Pg> for CustJsonbs {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
此函数的最后一行指示直接从返回值构造结构。这失败了,因为返回的值是一个数组而不是结构,如错误消息所示。
固定版本只会从 json 值构造内部数组并手动添加外部新类型包装器。
impl FromSql<Jsonb, Pg> for CustJsonbs {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(Self(serde_json::from_value(value)?))
// ^^^^ note the additional `Self` there
// Thats required to tell serde that we only want
// to construct the inner array from the provided json
}
}
``
您将如何为 Postgres Jsonb 类型设置 FromSql 和 ToSql 的 impl 函数,它可以是数据数组。
下面是一些示例数组 json 数据。
[
{
"title": "some text",
"date_str": null,
},
{
"title": "some more text",
"date_str": "Feb 25th",
},
]
这是我目前拥有的代码。我能够毫无问题地找出 none 数组实现,但我正在努力为包装类型 (Vec) 创建 ToSql 和 FromSql。我收到错误“Error(DeserializationError(error("invalid type: map, expaected a sequence", line: 0, column: 0)))”,我不确定我需要做什么更改。
// models.rs
#[derive(Debug, Serialize, Deserialize, Queryable, QueryableByName)]
#[table_name = "table"]
pub struct table {
pub id: i32,
pub cust_jsonb: CustJsonbs,
}
#[derive(FromSqlRow, AsExpression, Debug, Serialize, Deserialize)]
#[sql_type = "Jsonb"]
pub struct CustJsonb {
pub title: String,
pub date_arg: Option<String>,
}
//wrapper type
#[derive(FromSqlRow, AsExpression, Debug, Serialize, Deserialize)]
#[sql_type = "Jsonb"]
pub struct CustJsonbs (
Vec<CustJsonb>
);
// None array implementation that works
impl FromSql<Jsonb, Pg> for CustJsonb {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, Pg> for CustJsonb {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> diesel::serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as ToSql<Jsonb, Pg>>::to_sql(&value, out)
}
}
// Array implementation - I've tried (doesn't work and not sure how to fix it exactly)
impl FromSql<Jsonb, Pg> for CustJsonbs {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, Pg> for CustJsonbs {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> diesel::serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as ToSql<Jsonb, Pg>>::to_sql(&value, out)
}
}
所以这个问题的答案很简单。
impl FromSql<Jsonb, Pg> for CustJsonbs {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
此函数的最后一行指示直接从返回值构造结构。这失败了,因为返回的值是一个数组而不是结构,如错误消息所示。
固定版本只会从 json 值构造内部数组并手动添加外部新类型包装器。
impl FromSql<Jsonb, Pg> for CustJsonbs {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(Self(serde_json::from_value(value)?))
// ^^^^ note the additional `Self` there
// Thats required to tell serde that we only want
// to construct the inner array from the provided json
}
}
``