開発環境
- Macbook Pro M1 2020
- rustup 1.24.3 (ce5817a94 2021-05-31)
- mysql Ver 8.0.27 for macos12.0 on arm64 (Homebrew)
解決したいこと
今、RustでDieselを用いてMySQLにデータをCRUDする簡単なアプリケーションを作成しています。ここでプログラムにトランザクションを導入し、データベースを安全に利用したいと考えました。
トランザクション処理のクレートとしてtransaction-rsを選定しました。簡単なexampleも入っていたので手元の環境にコピーし、実行してみました。しかし、動きません。exampleはPostgresを使っていたので、自分のの環境用にデータベースの部分をMySQLへと書き換えました。
そしてわかる範囲でエラーをつぶしたのですが、まだ現状次のようなコンパイルエラーが残っています。
エラーメッセージ(抜粋)
error[E0277]: the trait bound `diesel::MysqlConnection: diesel::connection::Connection` is not satisfied --> src/main.rs:34:5 | 34 | transaction_diesel::run(&conn, tx).unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::connection::Connection` is not implemented for `diesel::MysqlConnection` | note: required by a bound in `transaction_diesel::run` --> /path/to/user/.cargo/registry/src/github.com-1ecc6299db9ec823/transaction-diesel-0.2.2/src/lib.rs:11:9 | 11 | Cn: diesel::Connection, | ^^^^^^^^^^^^^^^^^^ required by this bound in `transaction_diesel::run` error[E0277]: the trait bound `diesel::result::Error: From<diesel::result::Error>` is not satisfied --> src/main.rs:34:36 | 34 | transaction_diesel::run(&conn, tx).unwrap() | ^^ | | | expected an implementor of trait `From<diesel::result::Error>` | help: consider borrowing here: `&tx` | note: required by a bound in `transaction_diesel::run` --> /path/to/user/.cargo/registry/src/github.com-1ecc6299db9ec823/transaction-diesel-0.2.2/src/lib.rs:12:8 | 12 | E: From<diesel::result::Error>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transaction_diesel::run`
関係しそうなDieselのコード
DieselのGitHubのソースコードを確認するとMysqlConnectionはdiesel::Connectionを実装しているのに、mysql::connectionがプライベートになっていることに気づきました。
これのせいで該当のエラーが起きているように感じるが、ここを修正するのは正規の方法ではなさそうに感じています。
行き詰まってしまいました。
もし、このエラーの解決方法がわかる方がいらっしゃればご教示いただきたいです。
記述したコード
rust
1// main.rs 2#[macro_use] 3extern crate diesel; 4extern crate dotenv; 5extern crate transaction; 6extern crate transaction_diesel; 7 8mod db; 9mod model; 10mod schema; 11 12use diesel::mysql::MysqlConnection; 13use diesel::result::Error; 14use transaction::prelude::*; 15 16pub fn establish_connection() -> MysqlConnection { 17 use diesel::prelude::*; 18 use dotenv::dotenv; 19 use std::env; 20 21 dotenv().ok(); 22 23 let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); 24 MysqlConnection::establish(&database_url) 25 .expect(&format!("Error connecting to {}", database_url)) 26} 27 28fn main() { 29 let conn = establish_connection(); 30 let tx = with_ctx(|ctx| -> Result<(), Error> { 31 let size = db::create_user("keen").run(ctx)?; 32 println!("created user count: {:?}", size); 33 Ok(()) 34 }); 35 transaction_diesel::run(&conn, tx).unwrap() 36}
rust
1// db.rs 2use diesel::mysql::MysqlConnection; 3use diesel::prelude::*; 4use diesel::result::Error; 5use transaction::prelude::*; 6use transaction_diesel::with_conn; 7use transaction_diesel::DieselContext; 8 9use crate::model::*; 10use crate::schema::users::dsl; 11 12type Ctx<'a> = DieselContext<'a, MysqlConnection>; 13type BoxTx<'a, T> = Box<dyn Transaction<Ctx = Ctx<'a>, Item = T, Err = Error> + 'a>; 14 15pub fn create_user<'a>(name: &'a str) -> BoxTx<'a, usize> { 16 with_conn(move |cn| { 17 let size = diesel::insert_into(dsl::users) 18 .values(&NewUser { 19 name: name.to_string(), 20 }) 21 .execute(cn); 22 assert_eq!(Ok(1), size); 23 size 24 }) 25 .boxed() 26}
rust
1// model.rs 2use crate::schema::*; 3 4#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Hash, Queryable)] 5pub struct User { 6 pub id: i32, 7 pub name: String, 8} 9 10#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Hash, Insertable)] 11#[table_name = "users"] 12pub struct NewUser { 13 pub name: String, 14}
toml
1# Cargo.toml 2[package] 3name = "keen_transaction_mini_try" 4version = "0.1.0" 5edition = "2021" 6 7[dependencies] 8dotenv = "0.15.0" 9transaction = "0.2.1" 10transaction-diesel = "0.2.2" 11 12[dependencies.diesel] 13features = ["mysql"] 14version = "1.4.8"
ご覧くださりありがとうございます。ご回答のほど何卒よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/30 07:38