使用tokio-postgres读取PostgreSQL timestamp列失败求助
解决tokio-postgres读取PostgreSQL timestamp列的类型转换问题
问题根源
PostgreSQL的timestamp类型本质是无时区时间(timestamp without time zone),而你使用的chrono::DateTime<Utc>是带时区的UTC时间类型,二者无法直接映射,即使开启了tokio-postgres的with-chrono-0_4特性也会报错。
两种解决方案
方案1:修改数据库列类型(推荐)
将created列的类型改为timestamp with time zone(缩写timestamptz),这是存储带时区时间的标准做法,修改后你的原有代码直接就能正常读取:
let created_ : DateTime<Utc> = row.get("created");
方案2:代码中适配无时区时间
如果无法修改数据库结构,先使用chrono::NaiveDateTime(无时区时间类型)读取timestamp列,再根据业务场景转换为带时区的时间(假设数据库存储的是UTC时间):
use chrono::{NaiveDateTime, DateTime, Utc}; // ... 其他代码 ... for row in &rows { // ... 读取其他列 ... // 第一步:读取无时区的timestamp let created_naive: NaiveDateTime = row.get("created"); // 第二步:转换为UTC时间(根据实际存储的时区调整) let created_: DateTime<Utc> = DateTime::from_utc(created_naive, Utc); // ... 后续逻辑 ... }
为什么转字符串的尝试失败?
tokio-postgres不会自动将timestamp类型直接反序列化为&str,必须先读取为数据库类型对应的Rust类型(比如NaiveDateTime或tokio_postgres::types::Timestamp),再调用to_string()方法转换:
// 正确的字符串转换方式 let created_ts: tokio_postgres::types::Timestamp = row.get("created"); let created_str = created_ts.to_string(); // 再解析为chrono类型 let created_: DateTime<Utc> = DateTime::from_utc( NaiveDateTime::parse_from_str(&created_str, "%Y-%m-%d %H:%M:%S%.6f") .expect("Error parsing timestamp"), Utc, );
验证依赖配置
你的Cargo.toml配置是正确的,tokio-postgres的with-chrono-0_4特性已经启用,只要类型匹配就能正常工作。
内容的提问来源于stack exchange,提问作者user3761555
相关产品推荐
相关产品推荐

