Skip to main content
Version: v6 - stable

扩展数据类型

你尝试实现的类型很可能已包含在 DataTypes 中。如果未包含新的数据类型,本手册将展示如何自行编写。

¥Most likely the type you are trying to implement is already included in DataTypes. If a new datatype is not included, this manual will show how to write it yourself.

Sequelize 不会在数据库中创建新的数据类型。本教程介绍如何使 Sequelize 识别新数据类型,并假设这些新数据类型已在数据库中创建。

¥Sequelize doesn't create new datatypes in the database. This tutorial explains how to make Sequelize recognize new datatypes and assumes that those new datatypes are already created in the database.

要扩展 Sequelize 数据类型,请在创建任何 Sequelize 实例之前执行此操作。

¥To extend Sequelize datatypes, do it before any Sequelize instance is created.

示例

¥Example

在此示例中,我们将创建一个名为 SOMETYPE 的类型,它复制内置数据类型 DataTypes.INTEGER(11).ZEROFILL.UNSIGNED

¥In this example, we will create a type called SOMETYPE that replicates the built-in datatype DataTypes.INTEGER(11).ZEROFILL.UNSIGNED.

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;
}

创建此新数据类型后,你需要在每种数据库方言中映射此数据类型并进行一些调整。

¥After creating this new datatype, you need to map this datatype in each database dialect and make some adjustments.

PostgreSQL

假设 postgres 数据库中新数据类型的名称是 pg_new_type。该名称必须映射到 DataTypes.SOMETYPE。此外,还需要创建子 postgres 特定的数据类型。

¥Let's say the name of the new datatype is pg_new_type in the postgres database. That name has to be mapped to DataTypes.SOMETYPE. Additionally, it is required to create a child postgres-specific datatype.

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...

}

范围

¥Ranges

当新的范围类型为 在 postgres 中定义 后,将其添加到 Sequelize 中就很简单了。

¥After a new range type has been defined in postgres, it is trivial to add it to Sequelize.

在此示例中,postgres 范围类型的名称为 SOMETYPE_range,基础 postgres 数据类型的名称为 pg_new_typesubtypescastTypes 的键是 Sequelize 数据类型 DataTypes.SOMETYPE.key 的键,小写。

¥In this example the name of the postgres range type is SOMETYPE_range and the name of the underlying postgres datatype is pg_new_type. The key of subtypes and castTypes is the key of the Sequelize datatype DataTypes.SOMETYPE.key, in lower case.

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)

¥The new range can be used in model definitions as DataTypes.RANGE(DataTypes.SOMETYPE) or DataTypes.RANGE(DataTypes.SOMETYPE).