Node.jsでMySQL 8.0へ接続する
2019年一つ目の記事は、Node.jsでMySQLのDBへ接続するプログラムについてです。
いろいろな方がすでに記事を投稿されていますが、学んだことはアウトプットするのが今年の目標なので、
いつか見返す時のために記事にして残しておきます。
新年なので、環境系のフレームワークはとりあえず全部最新にしていきたいと思います。
何か問題があったらバージョン落とします。
■環境
OS: Windows 10 Home 64bit
DB: MySQL Server 8.0 Community Edition
node: v10.15.0
npm: 6.4.1
mysql: 2.16.0
■アウトライン
1. DBにテーブルを作成する
2. MySQLに接続するためのドライバをインストールする
3. DBに接続しSELECTするスクリプトを作成する
早速まとめていきたいと思います。
1. DBにテーブルを作成する。
簡単なテーブルを一つMySQLに作成します。
このテーブルにデータを入れたり、選択したりしていきます。
-- スキーマを作成する。 CREATE DATABASE `nodesample` DEFAULT CHARACTER SET utf8 ; -- スキーマ内にテーブルを作成する。 USE nodesample; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) NOT NULL, `age` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- サンプルに1件レコードを挿入する。 INSERT user(name, age) VALUES ('太郎', '30');
2. MySQLに接続するためのドライバをインストールする
MySQLへの接続のモジュール(ドライバ)としてmysqlが有名とのことで早速インストールします。
www.npmjs.com
コマンドプロンプトを開いて次のコマンドを実行します。
npm install mysql
しばらくたつとインストールが完了します。
package-lock.jsonをみると今回インストールしたmysqlは、2.16.0でした。
3. DBに接続しSELECTするスクリプトを作成する
mysqlのページを参考にとりあえずDBに接続するスクリプトを作成します。
/* sample.js */ 'use strict' const mysql = require('mysql'); const connection = mysql.createConnection({ host: '127.0.0.1', user: 'nodeuser', password: 'nodeuser', database: 'nodesample', }); // Connectionを定義する connection.connect(); let sql = 'select * from nodesample.user'; connection.query(sql, (err, rows, fields) => { if (err) throw err; console.log('userテーブル: ', rows); }); connection.end();
で次のコマンドで試してみるとエラーが発生しました。
node sample.js D:\workspace\MySQL-Sample\sample\sample.js:17 if (err) throw err; ^ Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client at Handshake.Sequence._packetToError (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\sequences\Sequence.js:47:14) at Handshake.ErrorPacket (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\sequences\Handshake.js:124:18) at Protocol._parsePacket (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\Protocol.js:278:23) at Parser.write (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\Parser.js:76:12) at Protocol.write (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\Protocol.js:38:16) at Socket.<anonymous> (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\Connection.js:91:28) at Socket.<anonymous> (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\Connection.js:502:10) at Socket.emit (events.js:182:13) at addChunk (_stream_readable.js:283:12) at readableAddChunk (_stream_readable.js:264:11) -------------------- at Protocol._enqueue (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\Protocol.js:144:48) at Protocol.handshake (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\protocol\Protocol.js:51:23) at Connection.connect (D:\workspace\MySQL-Sample\sample\node_modules\mysql\lib\Connection.js:118:18) at Object.<anonymous> (D:\workspace\MySQL-Sample\sample\sample.js:13:12) at Module._compile (internal/modules/cjs/loader.js:689:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10) at Module.load (internal/modules/cjs/loader.js:599:32) at tryModuleLoad (internal/modules/cjs/loader.js:538:12) at Function.Module._load (internal/modules/cjs/loader.js:530:3) at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
■エラーメッセージ
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server;
でグーグルを検索すると、Node.jsでMySQL 8.0へ接続しようとするときにみなさん発生しているようです。
一番参考になったのが下記ページの次のコメントでログイン時のパスワード認証が変更になっているのが、
mysqlで対応していないそうです。
node.js - MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client - Stack Overflow
This is because caching_sha2_password is introduced in MySQL 8.0, but the Node.js version is not implemented yet. You can see this pull request and this issue for more information. Probably a fix will come soon!
そのため、ログインユーザのパスワードをMySQL Wrokbenchから変更します。
※アカウント名とパスワードが同一なのはサンプルのためなので、普段は絶対にしないようにしましょう。
ALTER USER 'nodeuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'nodeuser'; FLUSH PRIVILEGES;
これで再度サンプルスクリプトを実行してみるとレコードを選択することができました。
node sample.js userテーブル: [ RowDataPacket { id: 1, name: '太郎', age: 30 } ]
■終わりに
今回RDBMSにMySQLを選択したのは、将来的にAWS Auroraへの移植を考えてSQL Server以外の製品を選択してみました。
SQL ServerはEnterprise版は2コアでいいお値段するので、SQL Serverを選択する理由はあまりなくなってきてしまいました。ただ、プレミアサポートなどのサポート体制があるのは強味ですね。
以上。