我正在尝试手动实现 sqlx::FrowRow
而不是使用 derive
,因为需要一些自定义初始化逻辑(例如将整数 i16
转换为枚举)。
默认 impl 是这样生成的:
use sqlx::FromRow;
impl FromRow for User {
fn from_row(row: &'r R) -> Result<Self, sqlx::Error> {
todo!()
}
}
但不清楚我应该使用什么生命周期和类型。
答案 0 :(得分:1)
FromRow
trait 非常通用,因为它用于可能支持不同类型的不同后端数据库。通过查看 #[derive(FromRow)]
生成的内容(通过 cargo expand
),您可以了解实现一个简单结构需要多少个通用约束:
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 })
}
}
它必须限制列可以按名称索引,并限制 String
和 i16
是有效的并且可以从数据库中解码。
自己动手,您可能最好选择您打算使用的 database Row
type (AnyRow
, MssqlRow
, MySqlRow
, PgRow
, { {1}}) 并为此实现它。此处对 postgres 使用 SqliteRow
:
PgRow
我确实想知道是否有不同的建议来进行自定义转换(通过 DTO 或其他机制)。