SQL UNIQUE制約をSequelizeのuniqueオプションに変換する

SQLのカラムレベルUNIQUE、テーブルレベルUNIQUE制約、複合ユニークインデックスがSequelizeモデル定義でどのように表現されるかを解説します。

Advanced Features

詳細な説明

Sequelizeでのユニーク制約

SQLにはユニーク制約を定義する3つの方法があり、コンバーターはそのすべてを処理します:カラムレベルのUNIQUE、テーブルレベルのUNIQUE制約、CREATE UNIQUE INDEX文。

カラムレベルのUNIQUE

email VARCHAR(255) NOT NULL UNIQUE
-- 変換後 -->
email: { type: DataTypes.STRING(255), allowNull: false, unique: true }

テーブルレベルのUNIQUE制約

CREATE TABLE team_members (
  team_id INTEGER NOT NULL,
  user_id INTEGER NOT NULL,
  role VARCHAR(50),
  UNIQUE (team_id, user_id)
);

複合ユニーク制約はindexes配列のエントリになります:

TeamMember.init({ ... }, {
  sequelize,
  indexes: [
    { fields: ['team_id', 'user_id'], unique: true },
  ],
});

CREATE UNIQUE INDEX

外部のユニークインデックス文も変換されます:

CREATE UNIQUE INDEX idx_email_org ON users(email, organization_id);
-- 変換後 -->
indexes: [
  { fields: ['email', 'organization_id'], unique: true },
]

単一 vs 複合

コンバーターは単一カラムと複合ユニーク制約を区別します:

  • 単一カラム: フィールド定義にunique: trueを設定
  • 複数カラム: モデルのindexes配列にunique: true付きのエントリを追加

バリデーション動作

unique: trueが設定されている場合、Sequelizeは:

  1. 挿入前に重複チェッククエリを実行(一部の設定で)
  2. 権威的な適用のためにデータベース制約に依存
  3. 制約が違反された場合にSequelizeUniqueConstraintErrorをスロー

この二層アプローチにより、アプリケーションは生のデータベースエラーではなくクリーンなJavaScriptエラーを取得します。

ユースケース

複数のテーブルに複合ユニーク制約(組織ごとにユニークなメールなど)があるマルチテナントSaaSデータベースを変換しており、コンバーターがこれらの制約をSequelizeのindexes設定に適切に反映する場合。

試してみる — SQL to Sequelize Model

フルツールを開く