isoppp

Knex.jsを使用したMigrationとSeedの作成

  • Knex.js
  • Hapi.js

TL;DR

Learn - Beginning API Development with Node.jsの続きです。
Knex.jsを使用したMigrationとSeedの作成を行います。

実装後はこちら ※若干githubで実装後に得た部分もあるので所々違いがあります。

準備

yarn add knex でパッケージをインストールしておく必要があります。

Migration

初期ファイル作成

CLIが用意されているので下記のコマンドを実行します。

yarn run knex migrate:make migration_name

実行すると migrations フォルダに YYYYMMDDHHMMSS_migration_name.js というフォーマットでファイルが作成されます。

exports.up = function(knex, Promise) {
  
};

exports.down = function(knex, Promise) {
  
};

exports.up はマイグレーション実行時に行われる内容、 exports.down が ロールバック時に実行される内容です。

実装

前回の動画の講座で提供されていた user テーブルに近しい物をKnex.jsで作ってみます。

SQLは下記でした。

CREATE TABLE user(
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(50),
  `email` VARCHAR(100),
  `password` VARCHAR(200)
);

これを若干変えつつ実装したものがこちらです。

exports.up = async (knex) => {
  await knex.schema.createTable('user', (t) => {
    t.increments()
    t.timestamps(false, true)
    t.string('name', 50).notNull()
    t.string('email', 100).notNull()
    t.string('password', 200).notNull()
  })
};

exports.down = async (knex) => {
  await knex.schema.dropTable('user')
}

解説

全体がasync/await形式になっています。これは後述するknex-migrateの影響もあるのでしなくても大丈夫です。

t.increments() を引数を省略して使用すると、 id というカラム名でプライマリーな INT / AUTO_INCREMENT が設定されたよくあるカラムが作成されます。

t.timestamps()created_atupdated_at のカラムをそれぞれdateTime型で作成します。
第一引数に true を設定すると、timestamp型が代わりに使用されます。
第二引数に true を設定すると、追加した時の時間をデフォルト値として設定します。

t.string() は オプションに文字列の長さを取り、文字列(VARCHAR)のカラムを設定します。第二引数を省略した場合は255がデフォルトです。

.notNull() はメソッドチェーンとして使用してそのカラムに NOT_NULL を設定します。

実行

yarn knex migrate:latest

実行すると最新の状態までmigrationファイルを実行します。

戻したい場合は yarn knex migrate:rollback で元に戻すことができます。

今回触れませんが、Knex.jsと互換性のある knex-migrateというmigration用のCLIツールがサードパーティであるのでこちらを使用した方が便利かもしれません。 up/downが細かくできるようになったりするのと生成コードがasync/await形式になります。

seed

初期ファイルの作成

yarn run knex seed:make seed_name

とすると seeds/seed_name.js が作成されます。
こちらは順番を保証するように作成してくれないので、必要であれば自身でナンバリング等を行ってください。

実装

こちらも動画で使用していた初期ユーザーと同じ物を作ります。

SQLはこちらでした

INSERT INTO `user` (`id`, `name`, `email`, `password`)
VALUES (NULL, 'Test User', 'user@example.com', MD5('u53rtest'));

それが今回はこんな感じになります。

const md5 = require('md5')

exports.seed = async (knex) => {
  await knex('user').del()
  await knex('user').insert([
    {
      name: 'Test User',
      email: 'user@example.com',
      password: md5('u53rtest'),
    },
  ])
}

実行

yarn run knex seed:run

以上で migrationで user というテーブルが作成されてその初期ユーザーがseedによって追加された状態になります。

おわりに

動画ではMySQLWorkBenchが登場していてjsで完結しないことにもやもやしていましたが、上記の実装を繰り返すことで全てjs化できます。

Knex自体はまだそこまでメジャーではないのか情報が少なめでした。
ただ公式のドキュメントは充実していると思うのでドキュメントを主軸にぐぐりを組み合わせると良い感じに実装できそうです。

参考