尝试使用 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)时,您必须确保检查相同的界限! 更喜欢构建特定的可重用函数,让您得到想要的东西 每次调用柴油方法时,您都在“包装”一个新语句,此新语句必须绑定,否则您会收到类似问题中的奇怪错误消息。 这些方法的结果通常在下面的代码中有一个简写形式,例如 FindLimit 您可以在第 27 行看到,我们必须嵌套 Limit&lt;Find&lt;..&gt;&gt;,对于您在查询链中调用的每个新方法,您都需要指定它。
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)),
        
    

我错过了什么?

通常人们可以猜到你试图做什么,我不认为你没有达到预期的结果是你的错。这种泛型编程很难理解,各种类型及其名称TU 很容易迷路。

如果我正确理解了Entity 所指的内容,那么您绑定在Entity 上的特征是错误的: Queryable&lt;Query, Database&gt; 表示可以在DatabaseQuery 中查询实现它的类型。如果你也不传入具体类型,那么“传入”类型 SqlQuery 是没有意义的! Insertable&lt;Tab&gt; 我猜是其他方法的遗留物? Identifiable 也一样?

【讨论】:

多么有见地的答案啊,非常感谢! :D

以上是关于尝试使用 Diesel 查询时溢出评估要求`_:Sized`的主要内容,如果未能解决你的问题,请参考以下文章

使用动态数量的 .and() 创建 Diesel.rs 查询

当使用与 tokio-diesel 关联时,“参数要求为 `'static` 借用 `record`”

使用 Diesel、r2d2 和 r2d2-diesel 查询数据库时出错

使用 Diesel 的 `belongs_to` 属性时“使用未声明的类型或模块”

Diesel 可以在运行时更改架构吗?

如何在 Diesel 中对 Postgres 数据库执行删除子查询?