Extending Data Types - 扩展数据类型

你尝试实现的类型很可能已经包含在数据类型中. 如果不包括新的数据类型,本手册将说明如何自己编写它.

Sequelize 不会在数据库中创建新的数据类型. 本教程说明了如何使 Sequelize 识别新数据类型,并假定这些新数据类型已在数据库中创建.

要扩展 Sequelize 数据类型,请在创建 Sequelize 实例之前进行.

示例

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

  1. const { Sequelize, DataTypes, Utils } = require('Sequelize');
  2. createTheNewDataType();
  3. const sequelize = new Sequelize('sqlite::memory:');
  4. function createTheNewDataType() {
  5. class SOMETYPE extends DataTypes.ABSTRACT {
  6. // 强制性的: 在数据库中完整定义新类型
  7. toSql() {
  8. return 'INTEGER(11) UNSIGNED ZEROFILL'
  9. }
  10. // 可选的: 验证器功能
  11. validate(value, options) {
  12. return (typeof value === 'number') && (!Number.isNaN(value));
  13. }
  14. // 可选的: sanitizer
  15. _sanitize(value) {
  16. // 强制所有数字为正
  17. return value < 0 ? 0 : Math.round(value);
  18. }
  19. // 可选的: 发送到数据库之前的值字符串化
  20. _stringify(value) {
  21. return value.toString();
  22. }
  23. // 可选的: 解析器,用于从数据库接收的值
  24. static parse(value) {
  25. return Number.parseInt(value);
  26. }
  27. }
  28. // 强制性的: 设置类型键
  29. SOMETYPE.prototype.key = SOMETYPE.key = 'SOMETYPE';
  30. // 强制性的: 将新类型添加到数据类型. 将其包装在 `Utils.classToInvokable` 上,
  31. // 以能够直接使用此数据类型,而不必调用 `new`.
  32. DataTypes.SOMETYPE = Utils.classToInvokable(SOMETYPE);
  33. // 可选的: 禁用字符串化后的转义. 这样做需要你自担风险,因为这为 SQL 注入提供了机会.
  34. // DataTypes.SOMETYPE.escape = false;
  35. }

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

PostgreSQL

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

  1. function createTheNewDataType() {
  2. // [...]
  3. const PgTypes = DataTypes.postgres;
  4. // 强制性的: 映射 postgres 数据类型名称
  5. DataTypes.SOMETYPE.types.postgres = ['pg_new_type'];
  6. // 强制性的: 使用自己的解析方法创建特定于 postgres 的子数据类型.
  7. // 解析器将动态映射到 pg_new_type 的 OID.
  8. PgTypes.SOMETYPE = function SOMETYPE() {
  9. if (!(this instanceof PgTypes.SOMETYPE)) {
  10. return new PgTypes.SOMETYPE();
  11. }
  12. DataTypes.SOMETYPE.apply(this, arguments);
  13. }
  14. const util = require('util'); // Node 包内置
  15. util.inherits(PgTypes.SOMETYPE, DataTypes.SOMETYPE);
  16. // 强制性的: 创建,覆盖或重新分配特定于 Postgres 的解析器
  17. // PgTypes.SOMETYPE.parse = value => value;
  18. PgTypes.SOMETYPE.parse = DataTypes.SOMETYPE.parse || x => x;
  19. // 可选的: 添加或覆盖特定于Postgres数据类型的方法,
  20. // 例如 toSql, escape, validate, _stringify, _sanitize...
  21. }

范围

postgres中定义了新的范围类型后,将其添加到 Sequelize 变得很简单.

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

  1. function createTheNewDataType() {
  2. // [...]
  3. // 添加 postgresql 范围,SOMETYPE 来自 DataType.SOMETYPE.key(小写)
  4. DataTypes.RANGE.types.postgres.subtypes.SOMETYPE = 'SOMETYPE_range';
  5. DataTypes.RANGE.types.postgres.castTypes.SOMETYPE = 'pg_new_type';
  6. }

新范围可在模型定义中用作 DataTypes.RANGE(DataTypes.SOMETYPE)DataTypes.RANGE(DataTypes.SOMETYPE).