尝试使用 Diesel 查询时溢出评估要求`_:Sized`
Posted
技术标签:
【中文标题】尝试使用 Diesel 查询时溢出评估要求`_:Sized`【英文标题】:Overflow evaluating the requirement `_: Sized` when trying to use Diesel queries 【发布时间】:2021-08-12 00:55:55 【问题描述】:我正在尝试为我正在构建的应用程序松散地实现存储库模式,但是我似乎无意中遇到了某种递归类型定义。
关于以下代码:
use diesel::pg::Pg, Insertable, Queryable, QueryDsl, PgConnection, Identifiable, Table;
use std::marker::PhantomData;
use anyhow::anyhow;
pub struct Repository<Entity, SqlType, Tab>
_entity_phantom: PhantomData<Entity>,
_type_phantom: PhantomData<SqlType>,
table: Tab,
impl <Entity, SqlType, Tab> Repository<Entity, SqlType, Tab>
where
Entity: Queryable<SqlType, Pg> + Insertable<Tab> + Identifiable,
Tab: Table
fn find_by_id(&self, id: i64, conn: &PgConnection) -> anyhow::Result<Entity>
match self.table.find(id).first::<Entity>(conn)
Ok(entity) => Ok(entity),
Err(e) => Err(anyhow!("", e)),
我得到错误:
error[E0275]: overflow evaluating the requirement `_: Sized`
--> support/src/lib.rs:18:26
|
18 | match self.table.find(id).first::<Entity>(conn)
| ^^^^
|
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`support`)
= note: required because of the requirements on the impl of `FilterDsl<_>` for `<Tab as AsQuery>::Query`
我尝试增加 crate 顶部的递归限制,但无济于事。将+ Sized
洒在整个特征范围内,似乎也没有任何作用。
我错过了什么?
【问题讨论】:
嗨,您有插入和更新的解决方案吗?柴油::insert_into(self.table) .values(data) .get_result::<:entity>(self.conn) 的特征是什么 【参考方案1】:此类错误通常意味着 diesel
无法解决您的特征界限,因为限制不够。
Diesel 泛型编程通常有点复杂,但这里有一些提示可以在您下次遇到此错误时帮助您:
每当您想使用特定方法(如find
)时,您必须确保还检查相同的界限!
更喜欢构建特定的可重用函数,让您得到想要的东西
每次调用柴油方法时,您都在“包装”一个新语句,此新语句必须绑定,否则您会收到类似问题中的奇怪错误消息。
这些方法的结果通常在下面的代码中有一个简写形式,例如 Find
或 Limit
您可以在第 27 行看到,我们必须嵌套 Limit<Find<..>>
,对于您在查询链中调用的每个新方法,您都需要指定它。
use anyhow::anyhow;
use diesel::
associations::HasTable,
dsl::Find, Limit,
query_dsl::
methods::FindDsl, LimitDsl,
LoadQuery,
,
PgConnection, RunQueryDsl, Table,
;
use std::marker::PhantomData;
pub struct Repository<Entity, Tab>
_entity_phantom: PhantomData<Entity>,
_table_phantom: PhantomData<Tab>,
impl<Entity, Tab> Repository<Entity, Tab>
where
Entity: HasTable<Table = Tab>,
Tab: Table,
fn find_by_id(&self, id: i64, conn: &PgConnection) -> anyhow::Result<Entity>
where
Tab: LimitDsl + FindDsl<i64>,
Find<Tab, i64>: LimitDsl + Table,
Limit<Find<Tab, i64>>: LoadQuery<PgConnection, Entity>,
match Entity::table().find(id).first::<Entity>(conn)
Ok(entity) => Ok(entity),
Err(e) => Err(anyhow!("", e)),
我错过了什么?
通常人们可以猜到你试图做什么,我不认为你没有达到预期的结果是你的错。这种泛型编程很难理解,各种类型及其名称T
、U
很容易迷路。
Entity
所指的内容,那么您绑定在Entity
上的特征是错误的:
Queryable<Query, Database>
表示可以在Database
到Query
中查询实现它的类型。如果你也不传入具体类型,那么“传入”类型 SqlQuery
是没有意义的!
Insertable<Tab>
我猜是其他方法的遗留物?
Identifiable
也一样?
【讨论】:
多么有见地的答案啊,非常感谢! :D以上是关于尝试使用 Diesel 查询时溢出评估要求`_:Sized`的主要内容,如果未能解决你的问题,请参考以下文章
使用动态数量的 .and() 创建 Diesel.rs 查询
当使用与 tokio-diesel 关联时,“参数要求为 `'static` 借用 `record`”
使用 Diesel、r2d2 和 r2d2-diesel 查询数据库时出错