質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

1回答

418閲覧

Rustでミスマッチタイプエラーを解決できない。

donut4

総合スコア170

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

1クリップ

投稿2024/07/24 13:02

編集2024/07/27 15:04

実現したいこと

rustでSeaOrmを使ってDBからデータをselectしたいのですが、コンパイルエラーを解決できなくなってしまいました。

SeaOrmの公式ドキュメントや、個人技術ブログなどを参考に、DBへの接続情報をSeaOrmのselectするメソッドに渡すように作っているのですが、後述するソースではうまくいかず、後述するコンパイルエラーがでてしまいます。

発生している問題・分からないこと

・エラー内容
(expected DatabaseConnectionと書かれているので、 let db:DatabaseConnection としているのですが解消できません。)
error[E0308]: mismatched types
--> src/main.rs:9:34
|
9 | let db:DatabaseConnection = check_connection();
| ------------------ ^^^^^^^^^^^^^^^^^^ expected DatabaseConnection, found future
| |
| expected due to this

該当のソースコード

src/main.rs

1mod database; 2use sea_orm::{DatabaseConnection, DbConn, DbErr, EntityTrait}; 3 4use crate::database::db_connection::check_connection; 5use crate::database::entities::*; 6use crate::database::entities::prelude::Employees; 7 8fn main() { 9 let db:DatabaseConnection = check_connection(); 10 select_employees(&db); 11} 12 13pub async fn select_employees(db: &DbConn) -> Result<Option<employees::Model>, DbErr> { 14 let selected: Option<employees::Model> = Employees::find_by_id(1).one(db).await?; 15 Ok(selected) 16}

src/database/db_connection.rs

1※DBコネクションに関する箇所のみ 2use std::env; 3use std::time::Duration; 4use dotenv::dotenv; 5use sea_orm::{ActiveModelTrait, ActiveValue, ConnectOptions, Database, DbConn, DbErr, DeleteResult, EntityTrait, QueryFilter}; 6use sea_orm::ActiveValue::Set; 7use crate::database::entities::{todos, users}; 8use crate::database::entities::prelude::Todos; 9use sea_orm::ColumnTrait; 10 11pub async fn check_connection() -> Result<(), DbErr> { 12 // DB接続のためのコネクションを生成 13 let db = establish_connection().await?; 14 15 assert!(db.ping().await.is_ok()); 16 db.clone().close().await.expect("panic!"); 17 println!("OK"); 18 Ok(()) 19} 20 21pub async fn establish_connection() -> Result<DbConn, DbErr> { 22 dotenv().ok(); 23 24 let url = env::var("DATABASE_URL").expect("DATABASE_URL is not found."); 25 26 let mut opt = ConnectOptions::new(url); 27 opt.max_connections(100) 28 .min_connections(5) 29 .connect_timeout(Duration::from_secs(8)) 30 .acquire_timeout(Duration::from_secs(8)) 31 .idle_timeout(Duration::from_secs(8)) 32 .max_lifetime(Duration::from_secs(8)) 33 .sqlx_logging(true) 34 .sqlx_logging_level(log::LevelFilter::Info); 35 36 // DB接続のためのコネクションを生成 37 Database::connect(opt).await 38}

修正後

src/main.rs

1fn main() { 2start(); 3} 4 5pub async fn select_employees(db: &DbConn) -> Result<Optionemployees::Model, DbErr> { 6let selected: Optionemployees::Model = Employees::find_by_id(1).one(db).await?; 7Ok(selected) 8} 9 10pub async fn start() { 11let db:DatabaseConnection = establish_connection().await.expect("connection error!"); 12let select_res:Optionemployees::Model = select_employees(&db).await.expect("database select error!"); 13println!("{}", select_res.unwrap().id); 14}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

上記のエラーメッセージと同様ですが画像のようにエラーが出ています。イメージ説明

補足

・db_connection.rsを参考にしたサイト
https://zenn.dev/collabostyle/articles/0641d73f776d80

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

expected DatabaseConnectionと書かれているので、 let db:DatabaseConnection としているのですが解消できません。

このエラーは、db変数の型を推論せずに明示的にDatabaseConnectionと記載しているからかなと思います。
db変数はDatabaseConnection型を期待している(expected)けど、check_connection関数の戻り値はResult<(), DbErr>型のためmismatched typesですね。

参考にしているサイトのソースコードだとGitHubの次のページの137行目あたりを見ると良いかなと思います。
sea-orm-postgresql-demo/src/lib.rs at main · codemountains/sea-orm-postgresql-demo · GitHub

check_connection関数はデータベースに接続できるかチェックするためのもののようですので、
コネクション(DatabaseConnection)を取得するのはestablish_connection関数の方みたいですね。

rust

1let db = establish_connection().await.expect("connection error!");

追記です。

コメントありがとうございます。
ビルドエラーが解消されたようで良かったです。

実行時のエラーも出なかったためDBの接続、selectまで実施されているようなのですがDBの値がコンソールに出力されませんでした。

警告なども出力されなかったでしょうか?
おそらく非同期のため実際の評価はされないままmainが終了してしまっているためかなと思いました。
下の例は"hello, world!"が出力されないです。

rust

1async fn hello_world() { 2 println!("hello, world!"); 3} 4fn main() { 5 hello_world(); // Nothing is printed 6 // warning: unused implementer of `Future` that must be used 7 // = note: futures do nothing unless you `.await` or poll them 8 // = note: `#[warn(unused_must_use)]` on by default 9}

下の例は"hello, world!"が出力されます。

rust

1use futures::executor::block_on; 2async fn hello_world() { 3 println!("hello, world!"); 4} 5fn main() { 6 let future = hello_world(); // Nothing is printed 7 block_on(future); // `future` is run and "hello, world!" is printed 8}

修正後の該当のソースコード(main.rs)の場合だとstartblock_onで囲めば良いことになるかなと思いました。

SeaORMの公式のドキュメントには下に引用したような記載があります。
非同期ランタイムはblock_onではなく、サードパーティのtokioが良く使われている印象でした。(Rustの非同期を検索すると上の方に出てくる)

Third, there are multiple async runtimes in Rust. async-std and tokio are the two most widely used. SeaORM's underlying driver, SQLx, supports both.
(機械翻訳)第3に、Rustには複数の非同期ランタイムがあります。async-stdとtokioが最も広く使われている2つです。SeaORMの基本ドライバであるSQLxは両方をサポートしています。

Async Programming | SeaORM 🐚 An async & dynamic ORM for Rust

下のリンク先なども参照してみると良いかなと思います。

async/.await Primer - Asynchronous Programming in Rust
Async Programming | SeaORM 🐚 An async & dynamic ORM for Rust


見当違いなことを書いてしまっていましたらごめんなさい・・
DBにはデータは登録されている前提で良いですよね?

投稿2024/07/25 13:15

編集2024/07/28 00:13
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

donut4

2024/07/27 15:02

返信ありがとうございます。 確かResult型はexpect()で推論すること忘れていました。 expect()を付与したらエラーが解消しました。 (awaitはasync内でしか使えないため別メソッドとして切り出しました) さらに質問してしまい恐縮ですが、 エラーが解消され、DBをから値を出力するためプログラムを実行してみました。 実行時のエラーも出なかったためDBの接続、selectまで実施されているようなのですがDBの値がコンソールに出力されませんでした。 修正後のsrc/main.rsの記載したので値の取り出し方法をお教えいただけないでしょうか?
donut4

2024/08/02 09:45

追記ありがとうございます。 すみません。原因は自分がずっと`cargo run`と間違えて`cargo build`をしていたしていたせいでした。 `cargo run`でうまく出力されました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問