メインコンテンツへスキップ
バージョン: v6 - 安定版

データ型の拡張

実装しようとしている型は、ほとんどの場合、DataTypes に含まれています。もし新しいデータ型が含まれていない場合は、このマニュアルで自分で作成する方法を説明します。

Sequelizeはデータベースに新しいデータ型を作成しません。このチュートリアルでは、Sequelizeに新しいデータ型を認識させる方法を説明し、それらの新しいデータ型がすでにデータベースに作成されていることを前提としています。

Sequelizeのデータ型を拡張するには、Sequelizeインスタンスを作成する前に行ってください。

この例では、組み込みのデータ型 DataTypes.INTEGER(11).ZEROFILL.UNSIGNED を複製する SOMETYPE という型を作成します。

const { Sequelize, DataTypes, Utils } = require('Sequelize');
createTheNewDataType();
const sequelize = new Sequelize('sqlite::memory:');

function createTheNewDataType() {
class SOMETYPE extends DataTypes.ABSTRACT {
// Mandatory: complete definition of the new type in the database
toSql() {
return 'INTEGER(11) UNSIGNED ZEROFILL';
}

// Optional: validator function
validate(value, options) {
return typeof value === 'number' && !Number.isNaN(value);
}

// Optional: sanitizer
_sanitize(value) {
// Force all numbers to be positive
return value < 0 ? 0 : Math.round(value);
}

// Optional: value stringifier before sending to database
_stringify(value) {
return value.toString();
}

// Optional: parser for values received from the database
static parse(value) {
return Number.parseInt(value);
}
}

// Mandatory: set the type key
SOMETYPE.prototype.key = SOMETYPE.key = 'SOMETYPE';

// Mandatory: add the new type to DataTypes. Optionally wrap it on `Utils.classToInvokable` to
// be able to use this datatype directly without having to call `new` on it.
DataTypes.SOMETYPE = Utils.classToInvokable(SOMETYPE);

// Optional: disable escaping after stringifier. Do this at your own risk, since this opens opportunity for SQL injections.
// DataTypes.SOMETYPE.escape = false;
}

この新しいデータ型を作成したら、各データベースダイアレクトでこのデータ型をマッピングし、いくつかの調整を行う必要があります。

PostgreSQL

新しいデータ型の名前がPostgresデータベースで pg_new_type であると仮定しましょう。その名前は DataTypes.SOMETYPE にマッピングする必要があります。さらに、Postgres固有の子データ型を作成する必要があります。

function createTheNewDataType() {
// [...]

const PgTypes = DataTypes.postgres;

// Mandatory: map postgres datatype name
DataTypes.SOMETYPE.types.postgres = ['pg_new_type'];

// Mandatory: create a postgres-specific child datatype with its own parse
// method. The parser will be dynamically mapped to the OID of pg_new_type.
PgTypes.SOMETYPE = function SOMETYPE() {
if (!(this instanceof PgTypes.SOMETYPE)) {
return new PgTypes.SOMETYPE();
}
DataTypes.SOMETYPE.apply(this, arguments);
}
const util = require('util'); // Built-in Node package
util.inherits(PgTypes.SOMETYPE, DataTypes.SOMETYPE);

// Mandatory: create, override or reassign a postgres-specific parser
// PgTypes.SOMETYPE.parse = value => value;
PgTypes.SOMETYPE.parse = DataTypes.SOMETYPE.parse || x => x;

// Optional: add or override methods of the postgres-specific datatype
// like toSql, escape, validate, _stringify, _sanitize...

}

範囲型

新しい範囲型がPostgresで定義された後、それをSequelizeに追加するのは簡単です。

この例では、Postgresの範囲型の名前は SOMETYPE_range で、Postgresの基礎となるデータ型の名前は pg_new_type です。 subtypescastTypes のキーは、Sequelizeのデータ型 DataTypes.SOMETYPE.key のキー(小文字)です。

function createTheNewDataType() {
// [...]

// Add postgresql range, SOMETYPE comes from DataType.SOMETYPE.key in lower case
DataTypes.RANGE.types.postgres.subtypes.SOMETYPE = 'SOMETYPE_range';
DataTypes.RANGE.types.postgres.castTypes.SOMETYPE = 'pg_new_type';
}

新しい範囲型は、モデル定義で DataTypes.RANGE(DataTypes.SOMETYPE) または DataTypes.RANGE(DataTypes.SOMETYPE) として使用できます。