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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

Rust

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

Q&A

解決済

1回答

2775閲覧

RustでDieselにtransaction-rsを試みるがdiesel::MysqlConnectionにdiesel::connection::Connectionが実装されていないと怒られる

akira_kano1101

総合スコア25

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

Rust

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

0グッド

0クリップ

投稿2021/12/29 15:51

編集2021/12/30 04:01

開発環境

  • 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"

ご覧くださりありがとうございます。ご回答のほど何卒よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは、作者です。
エラーの原因はtransaction-dieselの依存のdieselのバージョンと、お使いのdieselのバージョンが揃っていないからですね。transaction-dieselに合わせてdiesel 0.13 (1.3ではなくて0.13です。大分古いですね)を使えばコンパイルは通るかと思いますが、そもそもtransaction-rsをほとんどメンテナンスしていないので正直なところtransaction-rsを使うのを止めるのが無難じゃないかなと思います。

投稿2021/12/30 06:40

blackenedgold

総合スコア468

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

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

akira_kano1101

2021/12/30 07:38

Cargo.tomlを次のように修正し、 [package] name = "keen_transaction_mini_try" version = "0.1.0" edition = "2021" [dependencies] dotenv = "0.15.0" transaction = "0.2.1" transaction-diesel = "0.2.2" [dependencies.diesel] features = ["mysql"] version = "0.13.0" [dependencies.diesel_codegen] features = ["mysql"] version = "0.13.0" diesel::insert_intoがないようであるためdb.rsの一部(下記)を修正、 pub fn create_user<'a>(name: &'a str) -> BoxTx<'a, usize> { with_conn(move |cn| { diesel::insert(&NewUser { name: name.to_string(), }) .into(dsl::users) .execute(cn) }) .boxed() } main.rsにも下記を追加 #[macro_use] extern crate diesel_codegen; してみました。 しかし全く同じエラーが出ました。 お返事いただければ幸いです。 ただ、私ももうtransaction-rsはあきらめて別の方法(AnsiTransactionManagerが良さそうに感じている)でトランザクション処理を行おうと感じてはいます。 ご回答ありがとうございました。今後もよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問