为什么 Diesel 结构中的可选字段未实现特征

Why do I get a trait not implemented for an optional field in Diesel struct

我有这个结构:

#[table_name = "clients"]
#[derive(Serialize, Deserialize, Queryable, Insertable, Identifiable, Associations)]
pub struct Client {
    pub id: Option<i64>,
    pub name: String,
    pub rank: Option<i64>,
}

和以下实现:

impl Client {
    pub fn get(name: String, connection: &PgConnection) -> Option<Self> {
        match clients::table
            .filter(clients::name.eq(&name))
            .limit(1)
            .load::<Client>(connection)
        {
            Ok(clients) => Some(clients[0]),
            Err(_) => None,
        }
    }
}

这给了我以下错误:

.load::<Client>(connection) {                                                                                   
 ^^^^ the trait `diesel::Queryable<diesel::sql_types::BigInt, _>` is not implemented for `std::option::Option<i64>`

您的错误消息表明您无法将 BigInt(64 位整数)查询到 Option<i64>。那是因为您忘记说 idtable declaration 中可以为空。它必须看起来像:

table! {
    clients {
        id -> Nullable<BigInt>,
        name -> Text,
        rank -> Nullable<BigInt>,
    }
}

可以看到你要找的Queryable的实现in the documentation

对我来说,问题在于没有意识到柴油映射字段完全基于 结构中字段的顺序 它完全忽略字段名称

如果您的结构中的字段以与 schema.rs 文件不同的顺序定义,那么它将错误地映射它们并导致类型错误。

https://docs.diesel.rs/diesel/deserialize/trait.Queryable.html#deriving

When this trait is derived, it will assume that the order of fields on your struct match the order of the fields in the query. This means that field order is significant if you are using #[derive(Queryable)]. Field name has no effect.