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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:28:09