SequelizeとMySQLとExpressの簡単サンプル

# はじめに

こちらの記事「[Node.jsとExpressとMySQLの簡単サンプル](https://qiita.com/tiwu_official/items/9ffc8e1fd1173b1a9e40)」でNodeでMySQLを操作しました。

今回はNode向けのORMであるSequelizeを利用してMySQLを操作してみたいと思います。

# Sequelize

[公式サイト](http://docs.sequelizejs.com/)

PromiseベースのNode向けのORMで、PostgreSQL,MySQL,SQLite,MSSQLをサポートしているそうです。

ほんの少ししか触っていませんが、テーブルをModelとして扱う点はLaravelと似ているなと思いました（ORMのデファクトスタンダードなのか？ココらへんは無知・・・）

# 事前準備

[Node.jsとExpressとMySQLの簡単サンプル](https://qiita.com/tiwu_official/items/9ffc8e1fd1173b1a9e40)と同じく、先にデータを作成しておきます。

全て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`。

# とりあえずデータ取得

## ソースコード

[置き場](https://github.com/tiwuofficial/node-sample/blob/master/raw-sequelize/index.js)

##### index.js

```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()`で終了させています。

# モデルの利用

実はここで少しつまりました。（公式サイトをよく読んでいなかった）

最初公式通りに、モデルを利用するため下記のようなコードを書いていたのですが、エラーになる・・・。

```js
const TestTable = sequelize.define('test_table', {
  id: {
    type: Sequelize.INTEGER,
  },
  name: {
    type: Sequelize.STRING
  }
});

```

※下記のコードは公式

```js
const User = sequelize.define('user', {
  firstName: {
    type: Sequelize.STRING
  },
  lastName: {
    type: Sequelize.STRING
  }
});
```

## ソースコード

既存のテーブルからモデルを作るときはいくつか設定が必要っぽく、最終的に下記コードになりました。

[置き場](https://github.com/tiwuofficial/node-sample/blob/master/raw-sequelize/model.js)

##### model.js

```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の簡単サンプル](https://qiita.com/tiwu_official/items/9ffc8e1fd1173b1a9e40)と今回の組み合わせなので特に目新しいところはありません。

## ソースコード

[置き場](https://github.com/tiwuofficial/node-sample/blob/master/sequelize-express/index.js)

##### index.js

```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でマイグレーションをやってみようと思います。