1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ExpressでSequelizeを使う

Posted at

はじめに

ExpressでDBのSeederを使いたいと思って調べたところ、Sequelizeというライブラリがヒットしました。

今回はその使い方を調べたので、記事にしたいと思います。

環境構築

インストール

Sequelizeのライブラリをインストール

npm install sequelize

SequelizeをCLIで使うためのライブラリをインストール

npm install sequelize-cli --save-dev

MySQLを使用する場合下記も実行してください。
(ないと、migration実行時にエラーになります。)

npm install mysql2

初期化

以下のコマンドで初期化します。

npx sequelize init

実行すると、以下のファイルとフォルダが作成されます。

  • config/config.json
    接続設定を記載するファイルです。
  • models
    データベースのモデル用のファイルを配置するフォルダです。
  • migrations
    マイグレーション用のファイルを配置するフォルダです。
  • seeders
    シーダー用のファイルを配置するフォルダです。

接続設定

config/config.jsonにDB接続用の設定を記載します。

設定はdevelopmentなど環境ごとに設定できます。デフォルトで使用されるのはdevelopmentの設定となります。

{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

DBの初期化

DBにテーブルを定義し、データの挿入まで行う方法を説明します。
順番は以下になります。

  • モデル作成
  • マイグレーション実行
  • シーダー作成
  • シーダー実行

モデル作成

sequelize model:generate --name 名前 --attributes "属性"でモデルを作成します。
モデルを作成後、マイグレーションのコマンドを実行すると、DBにモデルと同等のテーブルが作成されます。
なので、上記のコマンドは以下のように読み換えることができます。
sequelize model:generate --name テーブル名 --attributes "列定義"

モデル名とテーブル名について
テーブル名の定義は複数形にする方もいると思いますが、複数形にするとモデルの名称も複数形になります。
回避方法があれば追記したいと思います。
どなたか情報ある方コメントしていただきたいです。

モデルを作成するサンプルコマンドを下記に記載しておきます。

npx sequelize model:generate --underscored --name users --attributes "name:string, age:integer"

自動生成される列について
以下の列は自動で生成されるので、model:generateで作成する列定義には含めない方が良いです。

  • id
  • created_at
  • updated_at

含めてもエラーにはなりませんが、定義内容が上書きされるみたいです。
具体的に記載すると下記のようなモデルファイルが作成されます。

'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      id: {
        type: Sequelize.INTEGER
      },
// 以下省略

idが二重で定義されて、下の方の設定で上書きされるみたいです。

実行するとmodelsにモデルのファイル、migrationsにマイグレーション用のファイルが作成されます。

マイグレーションを実行

モデル作成で、作成したマイグレーションファイルを実行します。

npx sequelize db:migrate

ターミナルで、MySQLを確認すると下記のようにテーブルが作成されます。

image.png

Seederを作成

以下のコマンドでSeederを作成します。

npx sequelize seed:generate --name sample-users

上記のコマンドで作成されたSeederファイルを編集し、どういうデータを作成するかを記載します。

'use strict';

/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up (queryInterface, Sequelize) {
    await queryInterface.bulkInsert('users', [
      {
        name: "Alice",
        age: 16,
        created_at: new Date(),
        updated_at: new Date(),
      },
      {
        name: "Bob",
        age: 30,
        created_at: new Date(),
        updated_at: new Date(),
      },
      { 
        name: 'Charlie', 
        age: 35, 
        created_at: new Date(), 
        updated_at: new Date() 
      },
      { 
        name: 'Diana', 
        age: 28, 
        created_at: new Date(), 
        updated_at: new Date() 
      },
      { 
        name: 'Evan', 
        age: 22, 
        created_at: new Date(), 
        updated_at: new Date() 
      }
    ]);
  },

  async down (queryInterface, Sequelize) {
    await queryInterface.bulkDelete('users', null, {});
  }
};

Seederを実行

以下のどちらかのコマンドで実行してください。

  • Seederファイルを全部実行する
    npx sequelize db:seed:all
  • Seederファイルを個別に実行する
    npx sequelize db:seed --seed ファイル名

以下のような形で挿入されます。

image.png

オプション

こちらの章では、外部キーの設定など詳細な設定方法を記載していきます。

外部キーの設定

外部キーの設定は、モデルのファイルとマイグレーションファイルに外部キーの設定を定義し、マイグレーションを行うことで設定できます。
DBの変更のみならマイグレーションファイルに設定だけで問題なさそうですが、モデルのファイルにも定義しておくとモデルを操作するときに便利になるそうです。

モデルを作成

サンプルとして、DBの初期化の続きからusersのidを外部キーに持つpostsというテーブルを作っていきたいと思います

npx sequelize model:generate --underscored --name posts --attributes "user_id:integer body:text"

modelsに外部キーを定義する

modelsのファイルに、associateというメソッドがあるのでそこで定義します。

users.js
'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class users extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      // ここで定義する
      users.hasMany(models.posts, {foreignKey: 'user_id'});
    }
  }
  users.init({
    id: DataTypes.INTEGER,
    name: DataTypes.STRING,
    age: DataTypes.INTEGER
  }, {
    sequelize,
    modelName: 'users',
    underscored: true,
  });
  return users;
};
posts.js
'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class posts extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      posts.belongsTo(models.users, { foreignKey: 'user_id'});
    }
  }
  posts.init({
    user_id: DataTypes.INTEGER,
    body: DataTypes.TEXT
  }, {
    sequelize,
    modelName: 'posts',
    underscored: true,
  });
  return posts;
};

マイグレーションファイルに外部キーを定義

migrationsxxxx-create-posts.jsの方に外部キーの定義を追加します。

xxxx-create-posts.js
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('posts', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      user_id: {
        type: Sequelize.INTEGER,
+       references: {
+         model: 'users', // 'users'は関連するモデルのテーブル名
+         key: 'id', // 'id'は参照先のフィールド名
+       },
      },
      // 省略
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('posts');
  }
};

参照先のキーにINDEXを追加

参照先となるキー(サンプルで言うとusersid)にINDEXを追加します。
追加しないとエラーになります。
usersのマイグレーションファイルに下記を追加してください。

xxxx-create-users.js
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('users', {
      // 省略
      updated_at: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
+   await queryInterface.addIndex('users', ['id'], {
+     unique: true,
+     name: 'id_index'
+   });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('users');
  }
};

マイグレーションを実行する

DBの初期化の続きから実行している場合、一旦マイグレーション実行前に戻します。

npx sequelize db:migrate:undo:all

その後、再度マイグレーションを実行します。

npx sequelize db:migrate

postsのテーブル定義をMySQLで確認すると、user_idにFOREIGN KEYの定義が追加されているはずです。

image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?