将数据解析为 Vec<T> 并将向量插入 postgresql

Posted

技术标签:

【中文标题】将数据解析为 Vec<T> 并将向量插入 postgresql【英文标题】:Parse data into Vec<T> and insert vector into postgresql 【发布时间】:2021-06-24 05:46:30 【问题描述】:

我收到一个插入到Vec&lt;T&gt; 中的 JSON 数组。我正在使用 serde 进行解析。我想将向量插入到数据库表中。 JSON数组解析得很好。 publication_time 字段带有时区,因此我使用 my_date_format 使用 serde 提供的 example 解析它。当我添加(派生)Insertable 到结构 cargo build 失败时

error[E0277]: the trait bound `DateTime<Local>: diesel::Expression` is not satisfied
 --> src/models.rs:5:23
  |
5 | #[derive(Deserialize, Insertable)]
  |                       ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `DateTime<Local>`
  |
  = note: required because of the requirements on the impl of `AsExpression<diesel::sql_types::Nullable<diesel::sql_types::Timestamp>>` for `DateTime<Local>`
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

models.rs:

use serde::Deserialize;
use chrono::DateTime, Local;
use crate::schema::readings;

#[derive(Deserialize, Insertable)]
struct Reading 
    #[serde(with = "my_date_format")]
    publication_time: DateTime<Local>,
    id: i32,
    index: i32,
    field_description: String,
    measurement: f32,

schema.rs:

table! 
    readings 
        measurement_time_default -> Nullable<Timestamp>,
        id -> Nullable<Integer>,
        index -> Nullable<Integer>,
        field_description -> Nullable<Text>,
        measurement -> Nullable<Float>,
    

Cargo.toml:

serde = "1"
serde_json = "1"
serde-datetime = "0.1.0"
diesel =  version = "1.4.4", features = ["postgres", "chrono"] 
chrono = "0.4.19"

我看到this 关于BigDecimal 的类似问题,但我的问题是DateTime&lt;Local&gt;。我在另一个项目中使用了chrono::NaiveDateTime,我也将数据插入到表中。在这个答案中,柴油正在使用的特定版本有linked。当我将类型更改为NaiveDateTime 时,serde 无法编译并出现此错误:

error[E0308]: mismatched types
 --> src/models.rs:5:10
  |
5 | #[derive(Deserialize, Insertable)]
  |          ^^^^^^^^^^^ expected struct `NaiveDateTime`, found struct `DateTime`
  |
  = note: expected struct `NaiveDateTime`
             found struct `DateTime<Local>`
  = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

【问题讨论】:

这个问题缺少提供完整答案的关键细节。请添加相应的架构定义和my_date_format 的实现。否则只能说DateTime&lt;Local&gt; 与任何柴油sql 类型都不兼容,因此您不能只将该类型用作Insertable 派生的一部分。 谢谢@weiznich。你解决了。我已经编辑了问题并添加了 schema.rs。然后我执行了一个新的搜索,发现docs.diesel.rs/diesel/pg/types/sql_types/… 使用了 Timestamptz。为了清楚起见,我添加了原始时间戳 【参考方案1】:

weiznich 包含 schema.rs 的评论为我指明了正确的方向。我将 Timestamp 更改为 Timestamptz。

schema.rs:

table! 
    readings 
        measurement_time_default -> Nullable<Timestamptz>,
        id -> Nullable<Integer>,
        index -> Nullable<Integer>,
        field_description -> Nullable<Text>,
        measurement -> Nullable<Float>,
    

Timestamptz 使用日期时间,如 here 所述。时间戳使用 NaiveDateTime。这解决了我的问题。

【讨论】:

以上是关于将数据解析为 Vec<T> 并将向量插入 postgresql的主要内容,如果未能解决你的问题,请参考以下文章

在向量中添加每个int 到一个字符串

如何在Rust中提高元素乘法的性能?

如何将 Rust `Vec<T>` 暴露给 FFI?

请问Opencv中 Vec<int, n>啥意思

在展开期间将向量成员推入向量:vector.push_back(vector[0])

在C++的模板类中创建向量