Node.jsで、AWS RDS(MySQL)のレコードの個数を取得するのに結構ハマったので、ここに記します。
##環境・システム構成
・node.js v14.5.0
・AWS Lambda から AWS RDS(MySQL)の情報を取得
##方法
SQL文でテーブルの中の数を取得するとき、 たとえば、 テーブル users の中の カラム userIDの数 を取得するには、以下のSQL文になります。
SELECT COUNT(*) from users where userId ='userID';
これを、Lambda内にnode.jsで書くと
'use strict';
const mysql = require('mysql');
exports.handler = function (event, context) => {
const connection = mysql.createConnection({
host : 'xxxx.xxxxxxx.ap-northeast-1.rds.amazonaws.com', //RDSのエンドポイント
user : 'admin', //MySQLのユーザ名
password : 'xxxxx', //MySQLのパスワード
database : 'xxxxx' //データベース名
});
let sql = "SELECT COUNT(*) from users where userId = '"+userId+"';";
connection.query( sql, function(err, rows, fields) {
if (err) throw err;
console.log(rows);
});
}
rowsに数が格納されているはずですが、
コンソールには
[ [RowDataPacket] ]
なんか、よくわからないので、
console.log(rows[0]);
とすると
RowDataPacket { 'COUNT(*)': 1 }
この'COUNT(*)'の値を取得しようと普通に考えると、
console.log(rows[0].RowDataPacket.COUNT(*));
ですが、これでは文法エラーになります。
SyntaxError: Unexpected token '*'
どうすればいいんだ。
SQL文の COUNT(*) の後ろに As count を入れたらいいです。
SELECT COUNT(*) AS count from users where userId ='userID';
お、なんかいい感じになってきました。
RowDataPacket { count: 1 }
しかし、実はこれは、JSONっぽいですが、JSONではありません。 RowDataPacketと出たときは、 JSON.stringify()で、 JSONに変換する必要があります。
console.log(JSON.stringify(rows[0]));
お、 いい感じ。
{
"count": 1
}
これでどうだ!
console.log(JSON.stringify(rows[0]).count);
と思ったら、あれ?
undefined
実は、 いったん parseしないといけません。
console.log(JSON.parse(JSON.stringify(rows[0])).count);
やっと数値をとることができました。
1
まとめますと、これが正解
'use strict';
const mysql = require('mysql');
exports.handler = function (event, context) => {
const connection = mysql.createConnection({
host : 'xxxx.xxxxxxx.ap-northeast-1.rds.amazonaws.com', //RDSのエンドポイント
user : 'admin', //MySQLのユーザ名
password : 'xxxxx', //MySQLのパスワード
database : 'xxxxx' //データベース名
});
let sql = "SELECT COUNT(*) AS count from users where userId = '"+userId+"';";
connection.query( sql, function(err, rows, fields) {
if (err) throw err;
console.log(JSON.parse(JSON.stringify(rows[0])).count);
});
}
##追記 (実はもっと簡単な方法が・・・)
ここまで読んでいただいて、ありがとうございます。
実は、こんな面倒なことをしなくても、簡単な方法がありました!
ツイッターで、親切な方が教えてくれました。
rows[n]で1つのオブジェクトになってるので、単にrows[0].countまたはrows[0]["count(*)"]でいけますよ!
— masaki ohashi (@ohashimasaki) June 17, 2021
これです。
console.log(rows[0].count);
つまり、
'use strict';
const mysql = require('mysql');
exports.handler = function (event, context) => {
const connection = mysql.createConnection({
host : 'xxxx.xxxxxxx.ap-northeast-1.rds.amazonaws.com', //RDSのエンドポイント
user : 'admin', //MySQLのユーザ名
password : 'xxxxx', //MySQLのパスワード
database : 'xxxxx' //データベース名
});
let sql = "SELECT COUNT(*) AS count from users where userId = '"+userId+"';";
connection.query( sql, function(err, rows, fields) {
if (err) throw err;
console.log(rows[0].count);
});
}
いやー、一体私は何をしてるやら・・・。
とはいえ、試行錯誤は大事です。
と自分に言い聞かせます。
##参考サイト
[How to get COUNT(*) variable] (https://github.com/mysqljs/mysql/issues/1519)