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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 03:45:11