SQL JSONとJSONBをSequelize DataTypesに変換する

SQL JSONとJSONBカラム型がSequelizeのDataTypes.JSONとDataTypes.JSONBにどのようにマッピングされるか、クエリとインデックスの考慮事項も含めて解説します。

Data Types

詳細な説明

SequelizeでのJSONカラム

最新のSQLデータベースはJSONストレージをネイティブでサポートしており、Sequelizeは2つの専用DataTypesを提供します:JSONJSONB。コンバーターはSQLカラム型に基づいてこれらを区別します。

JSON vs JSONB

特徴 DataTypes.JSON DataTypes.JSONB
ストレージ テキストベース バイナリ(パース済み)
クエリ演算子 限定的 フル(包含、キー存在)
インデックス インデックス不可 GINインデックス可能
データベース MySQL、PostgreSQL、SQLite PostgreSQLのみ

変換例

CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  metadata JSON,
  search_data JSONB,
  tags JSONB DEFAULT '[]'
);
Product.init({
  id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
  name: { type: DataTypes.STRING(255), allowNull: false },
  metadata: { type: DataTypes.JSON, allowNull: true },
  search_data: { type: DataTypes.JSONB, allowNull: true },
  tags: { type: DataTypes.JSONB, allowNull: true, defaultValue: '[]' },
}, { ... });

JSONカラムのクエリ

SequelizeはJSONクエリ用の特殊な演算子を提供します:

// PostgreSQL JSONB包含
Product.findAll({
  where: { metadata: { [Op.contains]: { color: 'red' } } }
});

// ネストされたキーアクセス
Product.findAll({
  where: { 'metadata.category': 'electronics' }
});

TypeScriptの型付け

TypeScriptモードでは、JSONカラムはobjectとして型付けされます。より厳密な型付けが必要な場合は、生成されたインターフェースを手動で改良できます:

interface ProductAttributes {
  metadata: { color: string; size: string } | null;
  search_data: Record<string, unknown> | null;
}

デフォルト値

SQLでのJSONデフォルト値(DEFAULT '{}'DEFAULT '[]'など)はSequelizeモデルで文字列リテラルとして保持されます。Sequelizeはレコード作成時にこれらを自動的にパースします。

ユースケース

JSONBとして格納される柔軟なメタデータを持つ商品カタログを構築しており、SQLスキーマを変換してSequelizeモデルがPostgreSQL固有のクエリ演算子用にJSONとJSONBを正しく区別する必要がある場合。

試してみる — SQL to Sequelize Model

フルツールを開く