首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何更好地实现sqlx::FromRow特性?

我如何更好地实现sqlx::FromRow特性?
EN

Stack Overflow用户
提问于 2021-03-19 10:46:36
回答 1查看 2.5K关注 0票数 5

我试图手动实现sqlx::FrowRow,而不是使用derive,因为需要一些自定义初始化逻辑(例如。将整数i16转换为枚举)。

默认的impl是这样生成的:

代码语言:javascript
复制
use sqlx::FromRow;

impl FromRow for User {
    fn from_row(row: &'r R) -> Result<Self, sqlx::Error> {
        todo!()
    }
}

但还不清楚,我应该用什么样的寿命和类型。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-19 18:41:31

FromRow特性非常通用,因为它用于可能支持不同类型的不同后端数据库。通过查看#[derive(FromRow)]生成的内容(通过cargo expand),您可以看到实现一个简单结构需要多少个泛型约束:

代码语言:javascript
复制
use sqlx::FromRow;

#[derive(FromRow)]
struct User {
    name: String,
    status: i16,
}

// generates

impl<'a, R: ::sqlx::Row> ::sqlx::FromRow<'a, R> for User
where
    &'a ::std::primitive::str: ::sqlx::ColumnIndex<R>,
    String: ::sqlx::decode::Decode<'a, R::Database>,
    String: ::sqlx::types::Type<R::Database>,
    i16: ::sqlx::decode::Decode<'a, R::Database>,
    i16: ::sqlx::types::Type<R::Database>,
{
    fn from_row(row: &'a R) -> ::sqlx::Result<Self> {
        let name: String = row.try_get("name")?;
        let status: i16 = row.try_get("status")?;
        ::std::result::Result::Ok(User { name, status })
    }
}

它必须约束列可以按名称索引,也必须约束Stringi16是有效的,并且可以从数据库中解码。

您最好自己选择要使用的database Row type (AnyRowMssqlRowMySqlRowPgRowSqliteRow)并实现它。在这里,将PgRow用于postgres:

代码语言:javascript
复制
use sqlx::{Row, FromRow, Error};
use sqlx::postgres::PgRow;

struct User {
    name: String,
    status: i16,
}

impl<'r> FromRow<'r, PgRow> for User {
    fn from_row(row: &'r PgRow) -> Result<Self, Error> {
        let name = row.try_get("name")?;
        let status = row.try_get("status")?;

        Ok(User{ name, status })
    }
}

不过,我想知道是否有不同的建议来执行自定义转换(通过DTO或其他机制)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66706700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档