Node.jsでMySQLのMigrationをする

# はじめに

前回「[Node.jsとExpressとMySQLの簡単サンプル](https://qiita.com/tiwu_official/items/9ffc8e1fd1173b1a9e40)」でNode.jsでMySQLの操作をしてみましたが、今回はDBの世界のスタンダード？（DBの世界は疎い）のMigrationをNode.jsで試してみました。

[今回のソース置き場](https://github.com/tiwuofficial/node-sample/tree/master/migration)

## スペック

- DB疎い
- migrationは少ししか理解していない


# Migration

DBスキーマのバージョン管理（と認識している）

新しくカラムが増やしたから他のコーダーの環境も増やそう！という時に便利という認識。

# db-migrate

[公式サイト](https://github.com/db-migrate/node-db-migrate)

nodeで使えるマイグレーションのパッケージ。

１週間前もコミットされていたので、活発に開発されていると思われる。

下記DBに対応しているとのこと。

- Mysql 
- PostgreSQL
- sqlite3 
- Mongodb


## インストール

`npm install db-migrate`

## db-migrate-mysql

`db-migrate`でmysqlを利用するためには、`db-migrate-mysql`というパッケージが必要なのでこれもインストールします。

`npm install db-migrate-mysql`

## 初期設定

db-migrateはdatabase.jsonというファイルで接続情報を管理する。

今回作ったdatabase.jsonは下記。

initとdevという名前で２つ作りました。

devはデフォルトの名前で、initは今回独自で作りました。

※なぜ２つかは後述

driverはDBの種類
userはDBにログインするユーザー名
passwordはuserのパスワード
databaseは利用するDB名

```json
{
  "init": {
    "driver": "mysql",
    "user": "root",
    "password": "root"
  },
  "dev": {
    "driver": "mysql",
    "user": "root",
    "password": "root",
    "database": "testDB"
  }
}
```

## DBの作成

公式サイト見ていたらDBを作ることができるそうなので、試してみました。

`db-migrate db:create testDB -e init`

上記コマンドでtestDBという名前のDBが作れます。

`-e init`をつけることでdatabase.jsonのinitの設定を適用できます。

database.jsonのinitとdevの違いは` "database": "testDB"`です。

最初devだけdatabase.jsonに書いて`db-migrate db:create testDB`とコマンドを打っていたのですが

testDBというDBがないぞ！とエラーを吐かれ（確かに存在しない）、苦肉の策がDBを作るようの設定であるinitを追加しました。

正しい対応方法なのか、そもそもDBを作る必要がないのかは謎ですが、とりあえずこれで作れます。

## DBの削除

DBの削除は`db-migrate db:drop testDB`で消せます。

## テーブルの作成、削除

テーブルの作成をするためにはまず、`db-migrate create`コマンドでマイグレーション用JSファイルを作成します。

　例 `db-migrate create create-table-pets`

作成したJSファイルの`exports.up`と`exports.down`の中身を修正します。

ファイル全体

```js
'use strict';

var dbm;
var type;
var seed;

/**
  * We receive the dbmigrate dependency from dbmigrate initially.
  * This enables us to not have to rely on NODE_PATH.
  */
exports.setup = function(options, seedLink) {
  dbm = options.dbmigrate;
  type = dbm.dataType;
  seed = seedLink;
};

exports.up = function(db) {
  return db.createTable('pets', {
    id: { type: 'int', primaryKey: true },
    name: 'string'
  });
};

exports.down = function(db) {
  return db.dropTable('pets');
};

exports._meta = {
  "version": 1
};

```

上記ファイルで実際に書いたコードは

```js
return db.createTable('pets', {
  id: { type: 'int', primaryKey: true },
  name: 'string'
});
```

と


```js
return db.dropTable('pets');
```

の２つです。

`createTable`は第１引数にテーブル名、第２引数にカラムの設定を書きます。

`dropTable`は引数にテーブル名を書きます。

マイグレーションの実行は`db-migrate up`と`db-migrate down`です。

`db-migrate up`では上記で作成した`exports.up`関数が実行されます。

上記例ではpetsテーブルが作成されます。
　
`db-migrate down`では上記で作成した`exports.down`関数が実行されます。

上記例ではpetsテーブルが削除されます。

## 追加

テーブルを作成するファイルを作った後、カラムを追加したいときはカラムを追加するファイルを作成します。

`db-migrate create add-age-column`

上記コマンドでファイルを作成し、作成したファイルの中身を修正します。

ファイル全体

```js
'use strict';

var dbm;
var type;
var seed;

/**
  * We receive the dbmigrate dependency from dbmigrate initially.
  * This enables us to not have to rely on NODE_PATH.
  */
exports.setup = function(options, seedLink) {
  dbm = options.dbmigrate;
  type = dbm.dataType;
  seed = seedLink;
};

exports.up = function(db) {
  return db.addColumn('pets','age',{ type: 'int' });
};

exports.down = function(db) {
  return db.removeColumn('pets','age');
};

exports._meta = {
  "version": 1
};
```

先ほどと同じく修正するのは、`exports.up`と`exports.down`です。

カラムの追加は`addColumn`関数を利用します。

第１引数にテーブル名、第2引数にカラム名、第3引数にカラムの設定を書きます。

```js
db.addColumn('pets','age',{ type: 'int' });
```

カラムの削除は`removeColumn`関数を利用します。

第１引数にテーブル名、第2引数にカラム名を書きます。

```js
db.removeColumn('pets','age');
```

ファイルを追加したら`db-migrate up`でカラムが追加されます。

# 所感

前回の記事ではMysqlにログインしてデータを作りましたが

db-migrateを使えば、ログインせずとも利用できそう。