gpt4 book ai didi

rust - 如何使用 `into_boxed()` 构建过滤表达式来针对带有联接的查询进行操作?

转载 作者:行者123 更新时间:2023-12-03 08:03:33 26 4
gpt4 key购买 nike

在柴油中,我想以编程方式建立 .filter() 的参数,但 rust 提示由于不满意而无法调用 into_boxed()特质界限。

#[macro_use]
extern crate diesel;
mod schema;
use diesel::{QueryDsl, ExpressionMethods, JoinOnDsl, NullableExpressionMethods};

fn main() {
use crate::schema::Foo::dsl as foo_dsl;
use crate::schema::Bar::dsl as bar_dsl;

let mut query = foo_dsl::Foo
.inner_join(bar_dsl::Bar
.on(bar_dsl::foo_id.eq(foo_dsl::id.nullable())))
.select((foo_dsl::id,)).into_boxed();

let mut filter = foo_dsl::id.eq(42).into_boxed();
filter = filter.and(bar_dsl::id.eq(17));

query = query.filter(filter);

}

投诉

Error[E0599]: the method `into_boxed` exists for struct `diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>`, but its trait bounds were not satisfied
--> src/main.rs:14:42
|
14 | let mut filter = foo_dsl::id.eq(42).into_boxed();
| ^^^^^^^^^^ method cannot be called on `diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>` due to unsatisfied trait bounds
|
::: /home/ross/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-1.4.8/src/expression/operators.rs:343:1
|
343 | diesel_infix_operator!(Eq, " = ");
| ---------------------------------
| |
| doesn't satisfy `_: QueryDsl`
| doesn't satisfy `_: Table`
|
= note: the following trait bounds were not satisfied:
`diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>: Table`
which is required by `diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>: QueryDsl`
`&diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>: Table`
which is required by `&diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>: QueryDsl`
`&mut diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>: Table`
which is required by `&mut diesel::expression::operators::Eq<Foo::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>: QueryDsl`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `and_or` due to previous error

如何针对具有联接的查询构建过滤器? BoxableExpression存在,但我的组合过滤器

filter = filter.and(bar_dsl::id.eq(17));

不适用于一张 table 。

这个示例显然可以在没有 filter 变量的情况下完成,并直接在查询的 .filter() 调用中完成。这是一个S.S.C.C.E .

可以以某种方式构建盒装过滤器吗?使用 BoxableExpression 还是使用 into_boxed()


schema.rs 看起来像:

table! {
use diesel::sql_types::*;

Bar (id) {
id -> Nullable<Integer>,
foo_id -> Nullable<Integer>,
}
}

table! {
use diesel::sql_types::*;

Foo (id) {
id -> Integer,
label -> Text,
}
}

joinable!(Bar -> Foo (foo_id));

allow_tables_to_appear_in_same_query!(
Bar,
Foo,
);

附注

有来自 this answer 的提示作者:@weiznich,

看来我可以找出有效的 BoxableExpression如:

    pub type QueryType = diesel::dsl::InnerJoin<foo_dsl::Foo, bar_dsl::Bar>;
let mut filter: Box<dyn BoxableExpression<QueryType, DB, SqlType = Bool>>
= Box::new(foo_dsl::id.eq(42));
filter = Box::new(filter.and(bar_dsl::id.eq(17)));

现在,当我使用 filter 变量时,例如

    query = query.filter(filter);

我明白了

error[E0277]: the trait bound `dyn BoxableExpression<diesel::query_builder::SelectStatement<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<Bar::columns::foo_id>, diesel::expression::nullable::Nullable<Foo::columns::id>>>>, Sqlite, SqlType = diesel::sql_types::Bool>: AppearsOnTable<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<Bar::columns::foo_id, diesel::expression::nullable::Nullable<Foo::columns::id>>>>` is not satisfied
--> src/main.rs:27:19
|
27 | query = query.filter(filter);
| ^^^^^^ the trait `AppearsOnTable<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<Bar::columns::foo_id, diesel::expression::nullable::Nullable<Foo::columns::id>>>>` is not implemented for `dyn BoxableExpression<diesel::query_builder::SelectStatement<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<Bar::columns::foo_id>, diesel::expression::nullable::Nullable<Foo::columns::id>>>>, Sqlite, SqlType = diesel::sql_types::Bool>`
|
= note: required because of the requirements on the impl of `AppearsOnTable<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<Bar::columns::foo_id, diesel::expression::nullable::Nullable<Foo::columns::id>>>>` for `Box<dyn BoxableExpression<diesel::query_builder::SelectStatement<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<Bar::columns::foo_id>, diesel::expression::nullable::Nullable<Foo::columns::id>>>>, Sqlite, SqlType = diesel::sql_types::Bool>>`
= note: required because of the requirements on the impl of `FilterDsl<Box<dyn BoxableExpression<diesel::query_builder::SelectStatement<JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<Bar::columns::foo_id>, diesel::expression::nullable::Nullable<Foo::columns::id>>>>, Sqlite, SqlType = diesel::sql_types::Bool>>>` for `diesel::query_builder::BoxedSelectStatement<'_, (diesel::sql_types::Integer,), JoinOn<diesel::query_source::joins::Join<Foo::table, Bar::table, Inner>, diesel::expression::operators::Eq<Bar::columns::foo_id, diesel::expression::nullable::Nullable<Foo::columns::id>>>, Sqlite>`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `and_or` due to previous error

p.p.s.

有趣。只要我不让查询into_boxed,我就可以使用BoxableExpression 进行编译。编译如下:

    pub type QueryType = diesel::dsl::InnerJoin<foo_dsl::Foo, bar_dsl::Bar>;
let mut filter: Box<dyn BoxableExpression<QueryType, DB, SqlType = Bool>>
= Box::new(foo_dsl::id.eq(42));
filter = Box::new(filter.and(bar_dsl::id.eq(17)));


let mut query = foo_dsl::Foo
.inner_join(bar_dsl::Bar.on(bar_dsl::foo_id.eq(foo_dsl::id.nullable())))
.filter(filter);

最佳答案

根据您的尝试和 self 回答,您似乎专注于使用单个 .filter() 调用并预先理清动态。但是,我鼓励您和 future 的查看者转而依赖 .into_boxed() 创建的盒装语句提供的灵活性:

use crate::Foo::dsl as foo_dsl;
use crate::Bar::dsl as bar_dsl;

let mut query = foo_dsl::Foo
.inner_join(bar_dsl::Bar.on(bar_dsl::foo_id.eq(foo_dsl::id.nullable())))
.into_boxed();

query = query.filter(foo_dsl::id.eq(42));
query = query.filter(bar_dsl::id.eq(17));

这更符合 Diesel 开发人员设计动态查询的方式。

  • into_boxed()说:“这对于您想要有条件地修改查询但需要类型保持不变的情况很有用。”

  • BoxableExpression说:“对于想要动态构建查询的情况,装箱查询通常更符合人体工程学。

关于rust - 如何使用 `into_boxed()` 构建过滤表达式来针对带有联接的查询进行操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73146073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com