The trait `LoadConnection` is not implemented for `&diesel::PgConnection`.

huangapple go评论94阅读模式
英文:

the trait `LoadConnection` is not implemented for `&diesel::PgConnection`

问题

  1. 我想用Rust创建一个REST API,但无法让它正常工作。
  2. 到目前为止,我的相关代码如下:
  3. main.rs 中:
  4. #[actix_web::main]
  5. async fn main() -> std::io::Result<()> {
  6. // 将 .env 加载到环境变量中。
  7. dotenv::dotenv().ok();
  8. env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
  9. // 设置数据库连接池
  10. let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL");
  11. let manager = ConnectionManager::<PgConnection>::new(database_url);
  12. let pool: DbPool = r2d2::Pool::builder()
  13. .test_on_check_out(true)
  14. .build(manager)
  15. .expect("Could not build connection pool");
  16. let port = std::env::var("PORT").expect("$PORT is not set.");
  17. HttpServer::new(move || {
  18. App::new()
  19. .app_data(web::Data::new(pool.clone()))
  20. .wrap(middleware::Logger::default())
  21. .route("/", web::get().to(|| async { "Actix REST API" }))
  22. .service(handlers::common::houses::index)
  23. })
  24. .bind(("0.0.0.0", port.parse().unwrap()))?
  25. .run()
  26. .await
  27. }
  28. 模式:
  29. diesel::table! {
  30. houses (id) {
  31. id -> Int4,
  32. user_id -> Varchar,
  33. street -> Varchar,
  34. figure -> Varchar,
  35. floor -> Varchar,
  36. create_date -> Timestamp,
  37. update_date -> Timestamp,
  38. is_deleted -> Bool,
  39. }
  40. }
  41. 模型:
  42. #[derive(Debug, Serialize, Deserialize, Queryable)]
  43. pub struct House {
  44. pub id: i32,
  45. pub user_id: String,
  46. pub street: String,
  47. pub figure: String,
  48. pub floor: String,
  49. pub create_date: chrono::NaiveDateTime,
  50. pub update_date: chrono::NaiveDateTime,
  51. pub is_deleted: bool,
  52. }
  53. 处理程序:
  54. #[get("/houses")]
  55. async fn index(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> {
  56. let houses = web::block(move || {
  57. let conn = &pool.get()?;
  58. find_all(&conn)
  59. })
  60. .await?
  61. .map_err(actix_web::error::ErrorInternalServerError)?;
  62. Ok(HttpResponse::Ok().json(houses))
  63. }
  64. fn find_all(conn: &PgConnection) -> Result<Vec<House>, DbError> {
  65. use crate::schemas::common::houses::houses::dsl::*;
  66. let items = houses.load::<House>(&mut conn)?;
  67. Ok(items)
  68. }
  69. 依赖项为:
  70. [dependencies]
  71. actix-web = "4"
  72. chrono = { version = "0.4.19", features = ["serde"] }
  73. diesel = { version = "2.0.3", features = ["postgres", "r2d2", "chrono"] }
  74. dotenv = "0.15.0"
  75. env_logger = "0.10.0"
  76. serde = { version = "1.0.136", features = ["derive"] }
  77. serde_json = "1.0"
  78. 它一直报错,我不明白原因。
  79. 错误信息为:
  80. error[E0277]: the trait bound `&diesel::PgConnection: LoadConnection` is not satisfied
  81. src\handlers\common\houses.rs:25:37
  82. | 25 | let items = houses.load::<House>(&mut conn)?;
  83. | ---- | -^^^^^^^^
  84. | | | the trait `LoadConnection` is not implemented for `&diesel::PgConnection`
  85. help: consider removing the leading `&`-reference required by a bound introduced by this call
  86. | note: required for `table` to implement `LoadQuery<'_, &diesel::PgConnection, House>`
  87. note: required by a bound in `diesel::RunQueryDsl::load`
  88. 我在 diesel 版本 1.4 中见过类似的错误,但我认为这个版本不同。
  89. 另外,我刚开始使用 Rust,目前有点迷茫。
  90. 我希望有人知道问题所在以及如何解决它。
英文:

I want to create a rest api with rust and can't make it work.

My relevant code so far:

In the main.rs:

  1. #[actix_web::main]
  2. async fn main() -&gt; std::io::Result&lt;()&gt; {
  3. // Loading .env into environment variable.
  4. dotenv::dotenv().ok();
  5. env_logger::init_from_env(env_logger::Env::new().default_filter_or(&quot;info&quot;));
  6. // set up database connection pool
  7. let database_url = std::env::var(&quot;DATABASE_URL&quot;).expect(&quot;DATABASE_URL&quot;);
  8. let manager = ConnectionManager::&lt;PgConnection&gt;::new(database_url);
  9. let pool: DbPool = r2d2::Pool::builder()
  10. .test_on_check_out(true)
  11. .build(manager)
  12. .expect(&quot;Could not build connection pool&quot;);
  13. let port = std::env::var(&quot;PORT&quot;).expect(&quot;$PORT is not set.&quot;);
  14. HttpServer::new(move || {
  15. App::new()
  16. .app_data(web::Data::new(pool.clone()))
  17. .wrap(middleware::Logger::default())
  18. .route(&quot;/&quot;, web::get().to(|| async { &quot;Actix REST API&quot; }))
  19. .service(handlers::common::houses::index)
  20. })
  21. .bind((&quot;0.0.0.0&quot;, port.parse().unwrap()))?
  22. .run()
  23. .await
  24. }

The schema:

  1. diesel::table! {
  2. houses (id) {
  3. id -&gt; Int4,
  4. user_id -&gt; Varchar,
  5. street -&gt; Varchar,
  6. figure -&gt; Varchar,
  7. floor -&gt; Varchar,
  8. create_date -&gt; Timestamp,
  9. update_date -&gt; Timestamp,
  10. is_deleted -&gt; Bool,
  11. }
  12. }

The model:

  1. #[derive(Debug, Serialize, Deserialize, Queryable)]
  2. pub struct House {
  3. pub id: i32,
  4. pub user_id: String,
  5. pub street: String,
  6. pub figure: String,
  7. pub floor: String,
  8. pub create_date: chrono::NaiveDateTime,
  9. pub update_date: chrono::NaiveDateTime,
  10. pub is_deleted: bool,
  11. }

The handler:

  1. #[get(&quot;/houses&quot;)]
  2. async fn index(pool: web::Data&lt;DbPool&gt;) -&gt; Result&lt;HttpResponse, Error&gt; {
  3. let houses = web::block(move || {
  4. let conn = &amp;pool.get()?;
  5. find_all(&amp;conn)
  6. })
  7. .await?
  8. .map_err(actix_web::error::ErrorInternalServerError)?;
  9. Ok(HttpResponse::Ok().json(houses))
  10. }
  11. fn find_all(conn: &amp;PgConnection) -&gt; Result&lt;Vec&lt;House&gt;, DbError&gt; {
  12. use crate::schemas::common::houses::houses::dsl::*;
  13. let items =houses.load::&lt;House&gt;(&amp;mut conn)?;
  14. Ok(items)
  15. }

The dependencies are:

  1. [dependencies]
  2. actix-web = &quot;4&quot;
  3. chrono = { version = &quot;0.4.19&quot;, features = [&quot;serde&quot;] }
  4. diesel = { version = &quot;2.0.3&quot;, features = [&quot;postgres&quot;, &quot;r2d2&quot;, &quot;chrono&quot;] }
  5. dotenv = &quot;0.15.0&quot;
  6. env_logger = &quot;0.10.0&quot;
  7. serde = { version = &quot;1.0.136&quot;, features = [&quot;derive&quot;] }
  8. serde_json = &quot;1.0&quot;`

It keeps giving an error, and I don't understand why.
The error is:

  1. `error[E0277]: the trait bound `&amp;diesel::PgConnection: LoadConnection` is not satisfied src\handlers\common\houses.rs:25:37
  2. | 25 | let items =houses.load::&lt;House&gt;(&amp;mut conn)?;
  3. | ---- -^^^^^^^^
  4. | | | the trait `LoadConnection` is not implemented for `&amp;diesel::PgConnection` help: consider removing the leading `&amp;`-reference required by a bound introduced by this call
  5. | note: required for `table` to implement `LoadQuery&lt;&#39;_, &amp;diesel::PgConnection, House&gt;` note: required by a bound in `diesel::RunQueryDsl::load`

I've seen a similar error with the diesel version 1.4, but I think that this version is different.
Plus I'm starting with rust and I'm a little lost in general at the moment.

I was hopping someone knows what the problem is and how to fix it.

答案1

得分: 0

  1. `PgConnection` 实现了 [`LoadConnection`](https://docs.rs/diesel/2.0.3/diesel/connection/trait.LoadConnection.html),但 `&amp;PgConnection` 不是(注意多余的 `&amp;`)。
  2. `conn` 变为可变引用并传递:
  3. ```rust
  4. #[get("/houses")]
  5. async fn index(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> {
  6. let houses = web::block(move || {
  7. let mut conn = pool.get()?; // <------------
  8. find_all(&mut conn) // <------------
  9. })
  10. .await?
  11. .map_err(actix_web::error::ErrorInternalServerError)?;
  12. Ok(HttpResponse::Ok().json(houses))
  13. }
  14. fn find_all(conn: &mut PgConnection) -> Result<Vec<House>, DbError> {
  15. // ^^^ <------------
  16. use crate::schemas::common::houses::houses::dsl::*;
  17. let items = houses.load::<House>(conn)?; // <------------
  18. Ok(items)
  19. }
英文:

PgConnection implements LoadConnection but &amp;PgConnection does not (note the extra &amp;).

Make conn mutable and pass as a mutable reference:

  1. #[get(&quot;/houses&quot;)]
  2. async fn index(pool: web::Data&lt;DbPool&gt;) -&gt; Result&lt;HttpResponse, Error&gt; {
  3. let houses = web::block(move || {
  4. let mut conn = pool.get()?; // &lt;------------
  5. find_all(&amp;mut conn) // &lt;------------
  6. })
  7. .await?
  8. .map_err(actix_web::error::ErrorInternalServerError)?;
  9. Ok(HttpResponse::Ok().json(houses))
  10. }
  11. fn find_all(conn: &amp;mut PgConnection) -&gt; Result&lt;Vec&lt;House&gt;, DbError&gt; {
  12. // ^^^ &lt;------------
  13. use crate::schemas::common::houses::houses::dsl::*;
  14. let items = houses.load::&lt;House&gt;(conn)?; // &lt;------------
  15. Ok(items)
  16. }

huangapple
  • 本文由 发表于 2023年2月7日 04:25:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75366208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定