はじめに
こちらの記事「Node.jsとExpressとMySQLの簡単サンプル」でNodeでMySQLを操作しました。
今回はNode向けのORMであるSequelizeを利用してMySQLを操作してみたいと思います。
Sequelize
PromiseベースのNode向けのORMで、PostgreSQL,MySQL,SQLite,MSSQLをサポートしているそうです。
ほんの少ししか触っていませんが、テーブルをModelとして扱う点はLaravelと似ているなと思いました(ORMのデファクトスタンダードなのか?ココらへんは無知・・・)
事前準備
Node.jsとExpressとMySQLの簡単サンプルと同じく、先にデータを作成しておきます。
全てmysqlログイン後
create database NodeTest;
use NodeTest;
create table test_table(id int(11),name varchar(255));
insert into test_table values(1,'testname');
インストール
npm install --save sequelize
利用するDBをインストール。
npm install --save pg pg-hstore
npm install --save mysql2
npm install --save sqlite3
npm install --save tedious
今回はMySQLのためnpm install --save mysql2
。
とりあえずデータ取得
ソースコード
index.js
const Sequelize = require('sequelize');
const sequelize = new Sequelize('NodeTest','root','root',{dialect:'mysql'});
sequelize.query("select * from test_table").spread((results, metadata) => {
console.log(results);
sequelize.close();
})
new Sequelize('データベース名','ユーザー','パスワード',{dialect:'mysql'});
データベース名は今回作成したNodeTest
ユーザーはroot
パスワードはroot
dialectの値は今回MySQLなのでmysqlを指定
sequelize.query
でSQLを実行し、結果を表示して、sequelize.close()
で終了させています。
モデルの利用
実はここで少しつまりました。(公式サイトをよく読んでいなかった)
最初公式通りに、モデルを利用するため下記のようなコードを書いていたのですが、エラーになる・・・。
const TestTable = sequelize.define('test_table', {
id: {
type: Sequelize.INTEGER,
},
name: {
type: Sequelize.STRING
}
});
※下記のコードは公式
const User = sequelize.define('user', {
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
}
});
ソースコード
既存のテーブルからモデルを作るときはいくつか設定が必要っぽく、最終的に下記コードになりました。
model.js
const Sequelize = require('sequelize');
const sequelize = new Sequelize('NodeTest','root','root',{dialect:'mysql'});
const TestTable = sequelize.define('test_table', {
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
name: {
type: Sequelize.STRING
}
},{
freezeTableName: true,
timestamps: false
});
TestTable.findAll().then(data => {
console.log(data);
});
まず、idにprimaryKeyの設定が必要です。
これは下記のようにエラーが出ていたので分かりやすかったです。
throw new Error(`A column called 'id' was added to the attributes of'${this.tableName}' but not marked with 'primaryKey: true'`);
次にfreezeTableNameですが、設定していないと下記のようなエラーが出ます。
Unhandled rejection SequelizeDatabaseError: Table 'nodetest.test_tables' doesn't exist
どうやら、test_tablesという名前のテーブルが存在しないと怒られます。
確かに作ったのはtest_tableなので、存在しません。
これは、Sequelizeはモデルの名前を自動的に複数形に変換するそうです。
そのため、変換させないためにfreezeTableNameを設定します。
次にtimestampsですが、設定していないと下記のようなエラーが出ます。
Unhandled rejection SequelizeDatabaseError: Unknown column 'createdAt' in 'field list'
createdAtというカラムが無いと怒られるのですが、test_tableにはありません・・・。
Sequelizeはデフォルトでタイムスタンプを記録するので、昨日をオフにするためにtimestampsを指定します。
これで、既存のテーブルのモデルが作成できました!
データの取得はfindAll
を使って取得できます。
ExpressとSequelize
最後にExpressとSequelizeを組み合わせてみます。
内容はNode.jsとExpressとMySQLの簡単サンプルと今回の組み合わせなので特に目新しいところはありません。
ソースコード
index.js
const express = require('express');
const app = express();
const Sequelize = require('sequelize');
const sequelize = new Sequelize('NodeTest','root','root',{dialect:'mysql'});
const TestTable = sequelize.define('test_table', {
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
name: {
type: Sequelize.STRING
}
},{
freezeTableName: true,
timestamps: false
});
app.get('/', function (req, res) {
TestTable.findAll().then(results => {
res.send(results);
});
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
所感
ORMになれないせいか、モデルという考え方が新鮮です。
今までSQLでしかDBを扱えなかったのが、JSのコードのみで扱えるのはすごい。
次はSequelizeでマイグレーションをやってみようと思います。