使用Rust sqlx时字段冲突问题及解决方案咨询
解决SQLx关联查询同名字段解析错误的方案
问题出在关联查询返回的结果集中存在id、title等同名字段,SQLx的FromRow解析时无法区分字段归属,导致Brand的字段值被Product的同名字段覆盖。以下是无需修改数据库字段的解决办法:
推荐方案:SQL字段别名 + 结构体sqlx(rename)映射
通过给SQL查询中的重名字段指定别名,再在结构体字段上用sqlx(rename)绑定别名,让SQLx精准匹配字段归属。
修改结构体定义
#[derive(FromRow, Serialize)] pub struct Brand { #[sqlx(rename = "brand_id")] id: i32, #[sqlx(rename = "brand_title")] title: String, #[sqlx(flatten)] product: Product } #[derive(FromRow, Serialize)] pub struct Product { #[sqlx(rename = "product_title")] title: String, #[sqlx(rename = "product_id")] id: i32, }
修改查询语句
let rows = query_as::<_, Brand>( "SELECT brands.id AS brand_id, brands.title AS brand_title, products.id AS product_id, products.title AS product_title FROM brands INNER JOIN products ON brands.id = products.brandId" ) .fetch_all(&pool) .await .unwrap();
备选方案:手动实现FromRow trait
如果不想修改查询语句,可以手动实现FromRow,通过字段索引精准获取对应值,但这种方式耦合查询的字段顺序,表结构变更时需要同步修改代码,维护成本较高:
use sqlx::{FromRow, Row, postgres::PgRow}; #[derive(Serialize)] pub struct Brand { id: i32, title: String, product: Product } #[derive(Serialize)] pub struct Product { title: String, id: i32, } impl FromRow<'_, PgRow> for Brand { fn from_row(row: &PgRow) -> sqlx::Result<Self> { Ok(Self { id: row.get(0), // 对应brands.id title: row.get(1), // 对应brands.title product: Product { id: row.get(2), // 对应products.id title: row.get(3), // 对应products.title } }) } }
内容的提问来源于stack exchange,提问作者DungeonMaster
相关产品推荐
相关产品推荐

