Node.js
MySQL
nodejs
knex

既存のDBを途中からknex.jsでスキーマ管理する

More than 1 year has passed since last update.

JavaScript 用の SQL Query Builder knex.js は,Rails Migration と同じようなことを node でもやりたいとなった時に非常に便利.
しかし,既に運用中の DB で knex.js を使おうとした時に,knex の DSL では,既存 DB と全く同じスキーマが再現できないケースがある.

再現できないケース

  • ON UPDATE CURRENT_TIMESTAMP が設定できない
  • id int(11) NOT NULL AUTO_INCREMENT が設定できず id int(10) unsigned NOT NULL AUTO_INCREMENT になる
  • floatprecision, scale なしで設定できず float(XXX, XXX) になる

knex.schema.row でスキーマを丸コピして対応

knex.schema.raw で直接スキーマデータを実行すればよい.
SHOW CREATE TABLE sample_table; で取得できるスキーマを記述する.

create_sample_table
const TABLE_NAME = 'sample_table';

exports.up = function (knex, Promise) {
    return knex.schema.hasTable(TABLE_NAME).then(function (exists) {
        if (!exists) {
            return knex.schema.raw(
                " CREATE TABLE `sample_table` (" +
                "   `id` bigint(20) NOT NULL AUTO_INCREMENT," +
                "   `title` varchar(255) NOT NULL," +
                "   `created_at` datetime NOT NULL," +
                "   `updated_at` datetime NOT NULL," +
                "   PRIMARY KEY (`id`)," +
                " ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;"
            );
        } else {
            return new Error("The table already exists");
        }
    });
};

exports.down = function (knex, Promise) {
    return knex.schema.hasTable(TABLE_NAME).then(function (exists) {
        if (exists) {
            return knex.schema.dropTable(TABLE_NAME);
        }
    });
};

knex実行

既存 DB に対しても knex migrate:latest を実行しても問題ない.
実行後,knex_migrations, knex_migrations_lock が生成されていることを確認する.

参考