Rust+SQLx查询PostgreSQL时NaiveDateTime类型转换编译错误
解决SQLx查询PostgreSQL时NaiveDateTime与PrimitiveDateTime的类型转换问题
问题原因
SQLx 0.7及以上版本中,PostgreSQL的timestamp(0) without time zone字段默认映射为chrono::PrimitiveDateTime类型,而非旧版本的NaiveDateTime。你的模型中使用NaiveDateTime,但SQLx从数据库读取的是PrimitiveDateTime,两者没有内置的From/Into转换实现,因此编译报错。
解决方案
方案1:直接替换模型字段类型为PrimitiveDateTime
这是最直接的解决方式,适配SQLx新版本的类型映射:
修改模型定义:
use chrono::PrimitiveDateTime; // 确保导入该类型 use serde::{Serialize, Deserialize}; use sqlx::FromRow; use uuid::Uuid; use serde_json::Value; #[derive(Serialize, Deserialize, Debug, FromRow)] pub struct Product { pub id: Uuid, pub name: String, pub category_id: String, pub kvp: Value, pub date: PrimitiveDateTime, // 替换为PrimitiveDateTime }
查询函数无需修改,query_as!可以正常工作:
pub async fn get_products(db_pool: &PgPool) -> Result<Vec<Product>, CustomError> { let products = sqlx::query_as!( Product, "SELECT id, name, category_id, kvp, date FROM products" ) .fetch_all(db_pool) .await .map_err(|e| match e { sqlx::Error::RowNotFound => CustomError::new_not_found("No products found".to_string()), sqlx::Error::Database(_) => CustomError::new_bad_request("Bad query".to_string()), _ => CustomError::new_internal(format!("Failed to fetch products: {}", e)), })?; Ok(products) }
方案2:手动转换为NaiveDateTime(若需保留原类型)
如果必须使用NaiveDateTime,可以放弃query_as!宏,改用sqlx::query手动处理行转换:
use chrono::{NaiveDateTime, PrimitiveDateTime}; pub async fn get_products(db_pool: &PgPool) -> Result<Vec<Product>, CustomError> { let products = sqlx::query("SELECT id, name, category_id, kvp, date FROM products") .map(|row: sqlx::postgres::PgRow| { let date: PrimitiveDateTime = row.get("date"); Ok(Product { id: row.get("id"), name: row.get("name"), category_id: row.get("category_id"), kvp: row.get("kvp"), date: NaiveDateTime::from_timestamp_opt(date.timestamp(), 0) .ok_or_else(|| CustomError::new_internal("Failed to convert timestamp".to_string()))?, }) }) .fetch_all(db_pool) .await?; Ok(products) }
注:这里利用
PrimitiveDateTime::timestamp()获取秒级时间戳,再构造NaiveDateTime,适配你的timestamp(0)(秒精度)字段。
额外说明
如果你的SQLx版本低于0.7,可能需要检查依赖版本,或者确保启用了正确的chrono特性。但建议优先升级到最新版并使用PrimitiveDateTime,以适配SQLx的官方类型映射规范。
内容的提问来源于stack exchange,提问作者NaviteLogger
相关产品推荐
相关产品推荐

