SQL JSONとJSONBをSequelize DataTypesに変換する
SQL JSONとJSONBカラム型がSequelizeのDataTypes.JSONとDataTypes.JSONBにどのようにマッピングされるか、クエリとインデックスの考慮事項も含めて解説します。
Data Types
詳細な説明
SequelizeでのJSONカラム
最新のSQLデータベースはJSONストレージをネイティブでサポートしており、Sequelizeは2つの専用DataTypesを提供します:JSONとJSONB。コンバーターは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を正しく区別する必要がある場合。