如何使用Rust Cornucopia处理Postgres HStore类型
解决Cornucopia不支持Postgres hstore类型的问题
办法1:在SQL查询中转换hstore为JSON(推荐)
放弃SELECT *的写法,明确列出字段,用Postgres内置函数hstore_to_json把hstore转成JSON格式,让Cornucopia自动映射到serde兼容类型:
SELECT id, username, email, hstore_to_json(identities) AS identities FROM users;
生成的Rust结构体里,identities字段会被自动映射为serde_json::Value。如果有自定义结构体(已实现Serialize和Deserialize),还能通过查询注释指定类型:
--! identities: crate::models::IdentityMap SELECT id, username, email, hstore_to_json(identities) AS identities FROM users;
示例自定义结构体:
use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] pub struct IdentityMap { pub provider: String, pub external_id: String, // 按需添加hstore对应键的字段 }
办法2:配置Cornucopia自定义类型映射
在项目根目录创建cornucopia.toml配置文件,添加hstore到Rust HashMap的类型映射,需先在Cargo.toml添加依赖:
postgres-hstore = "0.10" cornucopia-client = { version = "0.11", features = ["serde"] }
编写cornucopia.toml:
[types] hstore = { rust_type = "std::collections::HashMap<String, Option<String>>", deserializer = "postgres_hstore::from_hstore", serializer = "postgres_hstore::to_hstore" }
重新运行生成命令即可:
cornucopia --serialize live $DATABASE_URL
这样Cornucopia会自动把hstore字段映射为HashMap<String, Option<String>>,无需修改SQL查询。
办法3:避免SELECT *,手动解析hstore文本
如果不想修改配置或用JSON转换,可将hstore转成TEXT,在Rust代码中手动解析:
SELECT id, username, email, identities::TEXT AS identities FROM users;
生成的结构体中identities为String类型,用postgres-hstore的方法解析:
use postgres_hstore::from_hstore_str; use std::collections::HashMap; // 假设生成的结构体是User let user = get_users().await?; let identities_map: HashMap<String, Option<String>> = from_hstore_str(&user.identities).unwrap();
内容的提问来源于stack exchange,提问作者Asleepace
相关产品推荐
相关产品推荐

