You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust+PostgreSQL开发REST API遇数据类型适配问题求助

Rust对接PostgreSQL的类型适配问题解决

一、jsonb与serde_json::Value的转换问题

错误原因

PostgreSQL的jsonb字段与Rust的serde_json::Value之间的双向转换需要驱动提供专门的适配逻辑,默认情况下sqlx/diesel这类数据库驱动并未启用该逻辑,因此会抛出serde_json::Value未实现ToSql/FromSql trait的错误。

解决步骤(以sqlx为例)

  1. 启用对应Feature
    修改Cargo.toml,为sqlx添加jsonb和serde_json特性:
sqlx = { version = "0.7", features = ["postgres", "jsonb", "serde_json", "runtime-tokio-native-tls"] }
  1. 结构体字段映射
    直接用serde_json::Value对应数据库的jsonb字段:
use serde_json::Value;

#[derive(sqlx::FromRow, serde::Serialize, serde::Deserialize)]
struct ProductMeta {
    id: i32,
    specs: Value, // 对应PostgreSQL的jsonb类型字段
}
  1. 数据库操作示例
  • 插入数据:
let specs = serde_json::json!({"size": "L", "color": "black"});
sqlx::query!(
    "INSERT INTO product_meta (specs) VALUES ($1)",
    &specs as &Value
)
.execute(&db_pool)
.await?;
  • 查询数据:
let meta = sqlx::query_as!(ProductMeta, "SELECT id, specs FROM product_meta WHERE id = $1", 1)
.fetch_one(&db_pool)
.await?;

原理说明

PostgreSQL的jsonb是二进制序列化的JSON存储格式,serde_json::Value是Rust中通用的JSON值表示。驱动提供的jsonb特性封装了二者之间的序列化/反序列化逻辑:将Value序列化为jsonb的二进制格式写入数据库,或将jsonb数据解析为Value供Rust代码使用。默认不启用该特性是为了减少不必要的编译依赖。


二、Decimal金额字段的适配问题

解决步骤

  1. 添加依赖
    在Cargo.toml中添加rust_decimal库,并启用对应特性:
rust_decimal = { version = "1.30", features = ["serde", "postgres"] }
# 若使用sqlx,需额外启用decimal特性
sqlx = { version = "0.7", features = ["postgres", "decimal", ...] }
  1. 结构体字段映射
    用rust_decimal::Decimal对应PostgreSQL的numeric/decimal字段:
use rust_decimal::Decimal;

#[derive(sqlx::FromRow, serde::Serialize, serde::Deserialize)]
struct Order {
    id: i32,
    total_amount: Decimal, // 对应PostgreSQL的numeric(10,2)类型
}
  1. 数据库操作示例
  • 插入数据:
let amount = Decimal::from_str("299.99")?;
sqlx::query!(
    "INSERT INTO orders (total_amount) VALUES ($1)",
    amount
)
.execute(&db_pool)
.await?;
  • 查询数据:
let order = sqlx::query_as!(Order, "SELECT id, total_amount FROM orders WHERE id = $1", 1)
.fetch_one(&db_pool)
.await?;

原理说明

PostgreSQL的numeric是任意精度的十进制类型,Rust标准库未提供对应类型,rust_decimal库实现了符合IEEE 754标准的任意精度十进制运算。数据库驱动通过实现ToSql/FromSql trait,完成rust_decimal::Decimal与PostgreSQLnumeric类型之间的双向转换,保证金额计算的精度不会丢失。


三、避免同类问题的要点

  • 选择数据库驱动时,先查看官方文档的特性列表,PostgreSQL的特殊类型(如jsonb、numeric、array)通常需要启用对应特性才能支持
  • 对于Rust标准库没有的数据库类型,优先选择成熟的第三方适配库(如rust_decimal对应numeric,serde_json对应jsonb),避免手动实现复杂的类型转换逻辑
  • 遇到ToSql/FromSql未实现的错误时,首先检查是否启用了对应特性,其次确认是否使用了驱动支持的Rust类型

内容的提问来源于stack exchange,提问作者A G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:16:23