如何在PostgreSQL中用sqlx query_as搭配rust_decimal处理money类型
解决sqlx搭配rust_decimal处理PostgreSQL money类型的类型不匹配问题
问题场景
使用rust_decimal的Decimal类型搭配sqlx操作PostgreSQL的money字段时,出现类型不匹配错误:sqlx返回PgMoney类型,但结构体中定义的是Decimal,报错信息如下:
error[E0308]: mismatched types --> src/main.rs:38:14 | | let si = sqlx::query_as!( | ______________^ | | Item, | | r#" | | insert into inventory(name, price) | | | i.price | | ) | |_____^ expected struct `Decimal`, found struct `PgMoney`
涉及的表定义:
create table inventory ( id bigserial not null, name text not null, price money not null, constraint inventory_pk primary key (id) );
结构体定义:
pub struct Item { pub id: i64, pub name: String, pub price: Decimal, }
问题原因
sqlx默认将PostgreSQL的money类型映射为自身的PgMoney结构体,即使启用了decimal特性,也不会自动将money类型与rust_decimal的Decimal做关联映射。
解决方案
在SQL查询中显式将money类型转换为numeric类型,sqlx会自动将numeric映射为rust_decimal的Decimal。修改查询语句,在returning子句中对price字段做类型转换:
let si = sqlx::query_as!( Item, r#" insert into inventory(name, price) values ($1, $2) returning id, name, price::numeric as price "#, i.name, i.price ) .fetch_one(pool) .await?;
这样sqlx就能正确把查询结果中的price字段映射到结构体的Decimal类型上。
补充说明
如果需要插入时将Decimal传入money字段,sqlx会自动处理Decimal到PgMoney的转换(只要启用了decimal特性),无需额外操作,核心问题在于返回结果时的类型映射。
内容的提问来源于stack exchange,提问作者Barlog
相关产品推荐
相关产品推荐

