使用Rust sqlx宏查询PostgreSQL时遇_badge类型不支持问题求助
解决sqlx query_as!宏不支持自定义枚举数组类型的问题
问题根源
query_as!是编译时宏,需要明确的类型映射信息来匹配PostgreSQL列和Rust结构体字段。对于自定义枚举的数组类型(如badge[]),宏无法自动推断对应的PostgreSQL数组类型标识符_badge,同时你的User结构体缺少sqlx::FromRow派生,这是宏生成代码的必要条件。
解决方案
- 给
User结构体派生sqlx::FromRow - 在
badges字段上添加#[sqlx(type_name = "_badge")]属性,明确指定对应的PostgreSQL数组类型
修改后的代码
use sqlx::{FromRow, PgHasArrayType, PgTypeInfo}; use serde::{Serialize, Deserialize}; use uuid::Uuid; use chrono::{DateTime, Utc}; use std::fmt::Display; #[derive(sqlx::Type, Serialize, Deserialize, Display)] #[sqlx(type_name = "badge")] pub enum Badge { Sponsored, Founder, Developer, } impl PgHasArrayType for Badge { fn array_type_info() -> PgTypeInfo { PgTypeInfo::with_name("_badge") } fn array_compatible(ty: &PgTypeInfo) -> bool { ty.name() == "_badge" } } #[derive(Serialize, Deserialize, FromRow)] pub struct User { uuid: Uuid, date_joined: DateTime<Utc>, name: String, #[sqlx(type_name = "_badge")] badges: Vec<Badge>, articles: Vec<String>, followers: i64, }
关键说明
#[derive(FromRow)]:query_as!宏依赖这个trait生成数据库行到结构体的映射代码,非宏版本可能通过动态查询绕过了编译时检查,但宏必须显式拥有该trait。#[sqlx(type_name = "_badge")]:告诉宏该字段对应的PostgreSQL类型是_badge(badge枚举的数组类型),直接解决编译时类型不匹配的错误。- 优化
array_compatible方法:将原有的true改为精确匹配类型名称,避免潜在的类型兼容问题。
验证
修改后重新执行你的查询代码:
query_as!(User, r#"SELECT * FROM users WHERE name ILIKE $1"#, name)
编译错误应该会消失,宏可以正确识别并映射badge[]列到Vec<Badge>字段。
内容的提问来源于stack exchange,提问作者ImajinDevon
相关产品推荐
相关产品推荐

