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

Rust如何实现AStruct到tokio_postgres::Row的From转换及表插入

解答

直接结论

  • 无法合法实现impl From<AStruct> for tokio_postgres::Row
  • 手动构造的tokio_postgres::Row实例没有任何可用于插入数据的公开API,完全不能用来做插入操作

原因说明

tokio_postgres::Row从设计上就是数据库查询结果的只读载体,只在执行SELECT等查询语句后由客户端内部构造返回给用户,它的所有内部字段(你代码里写的statement/body/ranges)都是私有的,且没有提供任何公开的构造方法。这些字段存储的是数据库返回的原始二进制结果、关联的查询语句元数据、字段值偏移量,本质是绑定了一次查询返回上下文的只读结构,根本不是用来承载待写入数据的类型。

你尝试实现ToSql/FromSql的方向是对的,但搞错了Row的定位:tokio-postgres的写入逻辑完全不涉及Row类型,写入时只需要传入SQL语句,以及按顺序排列、实现了ToSql trait的参数列表即可。

正确实现方式

你已经为自定义类型实现了ToSql/FromSql,不需要做任何额外的Row转换,直接传参执行插入语句即可:

use chrono::{DateTime, Utc};
use tokio_postgres::{NoTls, Error, Row};
use tokio_postgres::types::{ToSql, FromSql};

// 注意:derive ToSql/FromSql时需要通过属性标记匹配数据库中定义的类型名
#[derive(ToSql, FromSql, Debug)]
#[postgres(name = "e")] // 对应数据库中提前创建的枚举类型
enum E {
    A,
    B,
}

#[derive(ToSql, FromSql, Debug)]
struct AStruct {
    i: i32,
    e: E,
    d: DateTime<Utc>
}

impl From<Row> for AStruct {
    fn from(row: Row) -> Self {
        Self {
            i: row.get(0),
            e: row.get(1),
            d: row.get(2),
        }
    }
}

// 可选:给AStruct加个辅助方法,快速生成插入参数列表,避免重复写参数
impl AStruct {
    fn insert_params(&self) -> Vec<&(dyn ToSql + Sync)> {
        vec![&self.i, &self.e, &self.d]
    }
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    let (client, _) = tokio_postgres::connect("database_url", NoTls).await?;
    let id = 1;

    let s = AStruct {
        i: 1,
        e: E::A,
        d: Utc::now(),
    };

    // 查询逻辑不需要改动
    let s: AStruct = client
        .query("SELECT i, e, d FROM structs WHERE id = $1", &[&id])
        .await?
        .into_iter()
        .next()
        .unwrap()
        .into();

    // 直接执行插入,传入参数即可,不需要构造Row
    client
        .execute(
            "INSERT INTO structs (i, e, d) VALUES ($1, $2, $3)",
            &s.insert_params()
        )
        .await?;

    Ok(())
}

如果你在数据库中把某张表的字段定义为和AStruct匹配的复合类型,甚至可以直接把整个结构体作为参数传入,不需要拆分成单独字段。

内容的提问来源于stack exchange,提问作者Neotenic Primate

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:01:07