DeserializationError - 未能填满整个缓冲区

DeserializationError - failed to fill whole buffer

我正在使用 Rocket 网络框架、Postgres 数据库和 Diesel 编写一个简单的 Rust 应用程序来管理数据库迁移。代码编译正常,应用程序的其他部分 运行 正确,但出于某种原因,我的 Expense 端点似乎无法正常工作。

例如,当点击 /expense 端点以获取所有费用时,我在日志中收到以下错误:

Err(
  DeserializationError(
    Error { 
      kind: UnexpectedEof, 
      message: "failed to fill whole buffer" 
    }
  )
)

这个错误显然不是很有用,而且没有太多细节。为什么我会收到此错误消息,我该如何解决此问题?

以下是代码的相关部分:

费用迁移

CREATE TABLE expenses (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL UNIQUE,
  description TEXT NULL,
  amount DECIMAL NOT NULL,
  tax_year INT NOT NULL,
  purchase_date TIMESTAMP WITH TIME ZONE NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

费用模型

#[derive( Debug, Serialize, AsChangeset, Deserialize, Queryable, Insertable )]
#[table_name = "expenses"]
pub struct Expense {
  pub id: Option<i32>,
  pub name: String,
  pub description: Option<String>,
  pub amount: BigDecimal,
  pub tax_year: i32,
  pub purchase_date: Option<DateTime<Utc>>,
  pub created_at: DateTime<Utc>,
  pub updated_at: DateTime<Utc>,
}

impl Expense {
  pub fn get_all(conn: &PgConnection) -> Result<Vec<Expense>, Error> {
    expenses::table.order(expenses::id.desc()).load::<Expense>(conn)
  }
  ...
}

控制器

#[get("/", format = "json")]
pub fn get_all(conn: db::Connection) -> Result<ApiResponse, ApiError> {
  let result = Expense::get_all(&conn);

  match result {
    Ok(r) => Ok(success(json!(r))),
    Err(e) => Err(db_error(e)),
  }
}

架构

table! {
  expenses (id) {
    id -> Nullable<Int4>,
    name -> Text,
    description -> Nullable<Text>,
    amount -> Numeric,
    tax_year -> Int4,
    purchase_date -> Nullable<Timestamptz>,
    created_at -> Timestamptz,
    updated_at -> Timestamptz,
  }
}

在数据库迁移中,您没有为 Diesel 期望的 amount 列 (DECIMAL) 指定精度。

尝试按照以下方式向 amount 列添加精度,然后重新应用迁移。

CREATE TABLE expenses (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL UNIQUE,
  description TEXT NULL,
  amount DECIMAL(6,2) NOT NULL,
  tax_year INT NOT NULL,
  purchase_date TIMESTAMP WITH TIME ZONE NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);