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

如何使用tokio_postgres插入timestamp类型数据?

解决Rust u32时间戳插入PostgreSQL timestamp字段的类型不匹配问题

问题原因

PostgreSQL的timestamp without time zone字段需要接收时间类型值,但tokio-postgres的ToSql trait默认并未实现u32到PostgreSQL Timestamp的直接转换——u32会被映射为PostgreSQL的integer类型,因此触发类型不匹配错误。

解决方案

方案1:使用chrono库转换为时间类型(推荐)

借助chrono库将u32秒级时间戳转换为NaiveDateTime(对应timestamp without time zone),该类型已实现ToSql trait,可直接作为参数传入。

  1. 添加依赖到Cargo.toml:
chrono = { version = "0.4", features = ["postgres"] }
  1. 修改代码:
use tokio_postgres::NoTls;
use chrono::NaiveDateTime;

let mut params: Vec<&(dyn ToSql + Sync)> = vec![];
let mut query = String::from("INSERT INTO tokens (created) VALUES ($1)");
let timestamp: u32 = 123;

// 将u32秒级时间戳转换为NaiveDateTime
let naive_dt = NaiveDateTime::from_timestamp_opt(timestamp as i64, 0)
    .expect("Invalid timestamp"); // 或用?处理错误,根据业务场景调整

params.push(&naive_dt as &(dyn ToSql + Sync));

let client = DB_POOL.get().await?;
client
    .execute(&query, &params)
    .await?;

方案2:在SQL中直接转换(无需额外依赖)

利用PostgreSQL内置的to_timestamp()函数,将传入的u32数值直接转换为timestamp类型,无需修改Rust端的类型转换逻辑。

修改后的代码:

use tokio_postgres::NoTls;

let mut params: Vec<&(dyn ToSql + Sync)> = vec![];
// 修改SQL,使用to_timestamp转换参数
let mut query = String::from("INSERT INTO tokens (created) VALUES (to_timestamp($1))");
let timestamp: u32 = 123;

params.push(&timestamp as &(dyn ToSql + Sync));

let client = DB_POOL.get().await?;
client
    .execute(&query, &params)
    .await?;

补充说明

  • 若你的u32时间戳是毫秒级而非秒级,方案1中需调整转换逻辑:NaiveDateTime::from_timestamp_millis(timestamp as i64);方案2中需用to_timestamp($1 / 1000.0)进行转换。
  • 方案1的优势是在Rust端完成类型校验,避免数据库层的转换开销;方案2更轻量,适合快速适配现有代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:22:12