【Ruby】MySQL に接続してみる その2
前置き
【Ruby】MySQL に接続してみる その1 - ぎょーぼのぶろぐ の記事の続きです。
前回、MySQL側のデータの準備を行いましたので、今回は、Ruby側から MySQL に接続して、データを参照してみます。
MySQL に接続するための gem をインストールする。
Ruby から MySQL へ接続するためには、Ruby用の MySQL クライアントが必要です。
2020/11/18 時点で、いろいろ種類があるみたいですが、「MySQL2」という gem が最も使われているようなので、こちらを使用します。
- 一番それっぽい名前の「MySQL」gem は、エラーでインストールできませんでした。gem のアップデートも 2013年でストップしているので、皆さん「MySQL2」へ移っているものと思われます。
「MySQL2」gem のインストールは、gem install
コマンドを使えば OK です。
> gem install mysql2
引数なしでインストールすると、バージョンは 「mysql2 (0.5.3 x64-mingw32)」となりました。 *1 ・・・メジャーバージョンが 0
なのはなんでだろ?
Ruby コードから、MySQL のデータを取得してみる
「Mysql2」 gem の使い方は、製作者の方が github 上に公開しています。
こちらを参考に、テーブルのデータを取得して表示するだけの、単純な Ruby のコードを書いてみます。手順としては、、、
mysql2
を require する。Mysql2::Client.new
でコネクションオブジェクトを生成する。- コネクションオブジェクトの
query
メソッドに SQL文を送って、結果を取得する。 - 結果を表示
実際のコードは下のような感じです。ファイル名は「mysql_test.rb」です。
require 'mysql2' client = Mysql2::Client.new(host: 'localhost', username: 'gyobo', password: 'password', encoding: 'utf8mb4', database: 'world') results= client.query('select * from country;') results.each do |row| puts "ID : #{row["id"]}, Name: #{row["name"]}" end
これで実行してみると・・・下のようにエラーが出てしまいます。
>ruby mysql_test.rb Traceback (most recent call last): 3: from mysql_test.rb:3:in `<main>' 2: from mysql_test.rb:3:in `new' 1: from C:/Ruby/Ruby26-x64/lib/ruby/gems/2.6.0/gems/mysql2-0.5.3-x64-mingw32/lib/mysql2/client.rb:90:in `initialize' (Mysql2::Error)64/lib/ruby/gems/2.6.0/gems/mysql2-0.5.3-x64-mingw32/lib/mysql2/client.rb:90:in `connect': Authentication plugin 'caching_sha2_password' cannot be loaded: ?w?肳?ꂽ???W???[??????????܂???B
エラーの原因:「mysql2」gem が caching_sha2_password に対応してないから
ポイントは、エラー文言の中の「Authentication plugin 'caching_sha2_password' cannot be loaded」の部分です。認証プラグイン'caching_sha2_password'がロードできない・・・
MySQL は、ユーザー認証の際に「認証プラグイン」というのを使うそうです。MySQL 5 のときは「mysql_native_password」がデフォルトだったのですが、MySQL 8 になってから「caching_sha2_password」というのが追加され、ユーザーの新規作成時、認証プラグインを指定しない場合は、デフォルトで「caching_sha2_password」となるそうです。そして、、、MySQLクライアントで「caching_sha2_password」に対応しているものが Ruby ではまだ無い(2020年11月現在)、、、ということみたいです。
「caching_sha2_password」に対応しているMySQLクライアントは、以下のリンク先で確認できます。
MySQL :: MySQL 8.0 Reference Manual :: 2.11.4 Changes in MySQL 8.0
このため、Ruby から MySQL 8 へ接続するためには、MySQL に接続するユーザーの認証プラグインをあらかじめ、「mysql_native_password」にしておく必要があります。。。
というわけで、MySQL にログインして、ユーザーの認証プラグインを「mysql_native_password」に変更します。
mysql> SELECT user, plugin FROM mysql.user WHERE user='gyobo'; +------------------+-----------------------+ | user | plugin | +------------------+-----------------------+ | gyobo | caching_sha2_password | +------------------+-----------------------+ 1 rows in set (0.00 sec) mysql> ALTER USER gyobo@localhost IDENTIFIED WITH mysql_native_password BY 'password'; Query OK, 0 rows affected (0.01 sec) mysql> SELECT user, plugin FROM mysql.user WHERE user='gyobo'; +------------------+-----------------------+ | user | plugin | +------------------+-----------------------+ | gyobo | mysql_native_password | +------------------+-----------------------+ 1 rows in set (0.00 sec)
こうして再度、実行してみると、、、
>ruby mysql_test.rb ID : 1, Name: 日本 ID : 2, Name: アメリカ ID : 3, Name: イギリス
データを取得することができました。
補足?蛇足?
ネットでいろいろ調べてみると、MySQL でユーザーを作成する際のデフォルトの認証プラグインを「mysql_native_password」に変更したらいい、という記事も見かけました。が、個人的にはそれはしない方がいいと思います。
理由は、「caching_sha2_password」 の方が、「mysql_native_password」よりもセキュリティ面では良いらしいから。
基本は、「caching_sha2_password」を使うようにして、今回のように「caching_sha2_passwordが対応してないから使えない」という場合に、必要な範囲で「mysql_native_password」に変更するようにすべき、と思われます。
*1:2020年11月18日現在です。