Model definition - 模型定义

    你还可以在每列上进行一些设置:

    1. const Foo = sequelize.define('foo', {
    2. // 如果未赋值,则自动设置值为 TRUE
    3. flag: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},
    4. // 设置默认时间为当前时间
    5. myDate: { type: Sequelize.DATE, defaultValue: Sequelize.NOW },
    6. // 将allowNull设置为false会将NOT NULL添加到列中,
    7. // 这意味着当列为空时执行查询时将从DB抛出错误。
    8. // 如果要在查询DB之前检查值不为空,请查看下面的验证部分。
    9. title: { type: Sequelize.STRING, allowNull: false},
    10. // 创建具有相同值的两个对象将抛出一个错误。 唯一属性可以是布尔值或字符串。
    11. // 如果为多个列提供相同的字符串,则它们将形成复合唯一键。
    12. uniqueOne: { type: Sequelize.STRING, unique: 'compositeIndex'},
    13. uniqueTwo: { type: Sequelize.INTEGER, unique: 'compositeIndex'},
    14. // unique属性用来创建一个唯一约束。
    15. someUnique: {type: Sequelize.STRING, unique: true},
    16. // 这与在模型选项中创建索引完全相同。
    17. {someUnique: {type: Sequelize.STRING}},
    18. {indexes: [{unique: true, fields: ['someUnique']}]},
    19. // primaryKey用于定义主键。
    20. identifier: { type: Sequelize.STRING, primaryKey: true},
    21. // autoIncrement可用于创建自增的整数列
    22. incrementMe: { type: Sequelize.INTEGER, autoIncrement: true },
    23. // 你可以通过'field'属性指定自定义字段名称:
    24. fieldWithUnderscores: { type: Sequelize.STRING, field: 'field_with_underscores' },
    25. // 这可以创建一个外键:
    26. bar_id: {
    27. type: Sequelize.INTEGER,
    28. references: {
    29. // 这是引用另一个模型
    30. model: Bar,
    31. // 这是引用模型的列名称
    32. key: 'id',
    33. // 这声明什么时候检查外键约束。 仅限PostgreSQL。
    34. deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE
    35. }
    36. }
    37. })

    注释选项也可以在表上使用, 查看 model configuration

    默认情况下,Sequelize 会将 createdAtupdatedAt 属性添加到模型中,以便您能够知道数据库条目何时进入数据库以及何时被更新。

    请注意,如果您使用 Sequelize 迁移,则需要将 createdAtupdatedAt 字段添加到迁移定义中:

    1. module.exports = {
    2. up(queryInterface, Sequelize) {
    3. return queryInterface.createTable('my-table', {
    4. id: {
    5. type: Sequelize.INTEGER,
    6. primaryKey: true,
    7. autoIncrement: true,
    8. },
    9. // 时间戳
    10. createdAt: Sequelize.DATE,
    11. updatedAt: Sequelize.DATE,
    12. })
    13. },
    14. down(queryInterface, Sequelize) {
    15. return queryInterface.dropTable('my-table');
    16. },
    17. }

    如果您不想在模型上使用时间戳,只需要一些时间戳记,或者您正在使用现有的数据库,其中列被命名为别的东西,直接跳转到 以查看如何执行此操作。

    数据类型

    以下是 Sequelize 支持的一些数据类型。 有关完整和更新的列表, 参阅 .

    1. Sequelize.STRING // VARCHAR(255)
    2. Sequelize.STRING(1234) // VARCHAR(1234)
    3. Sequelize.STRING.BINARY // VARCHAR BINARY
    4. Sequelize.TEXT // TEXT
    5. Sequelize.TEXT('tiny') // TINYTEXT
    6. Sequelize.INTEGER // INTEGER
    7. Sequelize.BIGINT // BIGINT
    8. Sequelize.BIGINT(11) // BIGINT(11)
    9. Sequelize.FLOAT // FLOAT
    10. Sequelize.FLOAT(11) // FLOAT(11)
    11. Sequelize.FLOAT(11, 12) // FLOAT(11,12)
    12. Sequelize.REAL // REAL PostgreSQL only.
    13. Sequelize.REAL(11) // REAL(11) PostgreSQL only.
    14. Sequelize.REAL(11, 12) // REAL(11,12) PostgreSQL only.
    15. Sequelize.DOUBLE // DOUBLE
    16. Sequelize.DOUBLE(11) // DOUBLE(11)
    17. Sequelize.DOUBLE(11, 12) // DOUBLE(11,12)
    18. Sequelize.DECIMAL // DECIMAL
    19. Sequelize.DECIMAL(10, 2) // DECIMAL(10,2)
    20. Sequelize.DATE // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres
    21. Sequelize.DATE(6) // DATETIME(6) for mysql 5.6.4+. Fractional seconds support with up to 6 digits of precision
    22. Sequelize.DATEONLY // DATE without time.
    23. Sequelize.BOOLEAN // TINYINT(1)
    24. Sequelize.ENUM('value 1', 'value 2') // An ENUM with allowed values 'value 1' and 'value 2'
    25. Sequelize.ARRAY(Sequelize.TEXT) // Defines an array. PostgreSQL only.
    26. Sequelize.ARRAY(Sequelize.ENUM) // Defines an array of ENUM. PostgreSQL only.
    27. Sequelize.JSON // JSON column. PostgreSQL, SQLite and MySQL only.
    28. Sequelize.JSONB // JSONB column. PostgreSQL only.
    29. Sequelize.BLOB // BLOB (bytea for PostgreSQL)
    30. Sequelize.BLOB('tiny') // TINYBLOB (bytea for PostgreSQL. Other options are medium and long)
    31. Sequelize.UUID // UUID datatype for PostgreSQL and SQLite, CHAR(36) BINARY for MySQL (use defaultValue: Sequelize.UUIDV1 or Sequelize.UUIDV4 to make sequelize generate the ids automatically)
    32. Sequelize.RANGE(Sequelize.INTEGER) // Defines int4range range. PostgreSQL only.
    33. Sequelize.RANGE(Sequelize.BIGINT) // Defined int8range range. PostgreSQL only.
    34. Sequelize.RANGE(Sequelize.DATE) // Defines tstzrange range. PostgreSQL only.
    35. Sequelize.RANGE(Sequelize.DATEONLY) // Defines daterange range. PostgreSQL only.
    36. Sequelize.RANGE(Sequelize.DECIMAL) // Defines numrange range. PostgreSQL only.
    37. Sequelize.ARRAY(Sequelize.RANGE(Sequelize.DATE)) // Defines array of tstzrange ranges. PostgreSQL only.
    38. Sequelize.GEOMETRY // Spatial column. PostgreSQL (with PostGIS) or MySQL only.
    39. Sequelize.GEOMETRY('POINT') // Spatial column with geometry type. PostgreSQL (with PostGIS) or MySQL only.
    40. Sequelize.GEOMETRY('POINT', 4326) // Spatial column with geometry type and SRID. PostgreSQL (with PostGIS) or MySQL only.

    BLOB数据类型允许您将数据作为字符串和二进制插入。 当您在具有BLOB列的模型上执行find或findAll时,该数据将始终作为二进制返回。

    如果你正在使用PostgreSQL TIMESTAMP WITHOUT TIMEZONE,您需要将其解析为不同的时区,请使用pg库自己的解析器:

    1. require('pg').types.setTypeParser(1114, stringValue => {
    2. return new Date(stringValue + '+0000');
    3. // 例如UTC偏移。 使用你想要的任何偏移。
    4. });

    除了上述类型之外,integer,bigint,float和double也支持unsigned和zerofill属性,可以按任何顺序组合:
    请注意,这不适用于PostgreSQL!

    1. Sequelize.INTEGER.UNSIGNED // INTEGER UNSIGNED
    2. Sequelize.INTEGER(11).UNSIGNED // INTEGER(11) UNSIGNED
    3. Sequelize.INTEGER(11).ZEROFILL // INTEGER(11) ZEROFILL
    4. Sequelize.INTEGER(11).ZEROFILL.UNSIGNED // INTEGER(11) UNSIGNED ZEROFILL
    5. Sequelize.INTEGER(11).UNSIGNED.ZEROFILL // INTEGER(11) UNSIGNED ZEROFILL

    上面的例子只显示整数,但是可以用bigint和float来完成

    用对象表示法:

    1. // 对于枚举:
    2. sequelize.define('model', {
    3. states: {
    4. values: ['active', 'pending', 'deleted']
    5. }
    6. })

    此项仅支持 PostgreSQL.

    Array(ENUM) 类型需要特殊处理。 每当 Sequelize 与数据库通信时,它必须使用 ENUM 名称对数组值进行类型转换。

    所以这个枚举名必须遵循 enum_<table_name>_<col_name> 这个模式。 如果您正在使用 sync,则会自动生成正确的名称。

    范围类型

    由于范围类型具有其绑定的包含(inclusive)/排除(exclusive)的额外信息,所以使用一个元组在javascript中表示它们并不是很简单。

    将范围作为值提供时,您可以从以下API中进行选择:

    1. // 默认为 '["2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00")'
    2. // 包含下限, 排除上限
    3. Timeline.create({ range: [new Date(Date.UTC(2016, 0, 1)), new Date(Date.UTC(2016, 1, 1))] });
    4. // 控制包含
    5. const range = [new Date(Date.UTC(2016, 0, 1)), new Date(Date.UTC(2016, 1, 1))];
    6. range.inclusive = false; // '()'
    7. range.inclusive = [false, true]; // '(]'
    8. range.inclusive = true; // '[]'
    9. range.inclusive = [true, false]; // '[)'
    10. // 或作为单个表达式
    11. const range = [
    12. { value: new Date(Date.UTC(2016, 0, 1)), inclusive: false },
    13. ];
    14. // '("2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00"]'
    15. // 复合形式
    16. const range = [
    17. { value: new Date(Date.UTC(2016, 0, 1)), inclusive: false },
    18. new Date(Date.UTC(2016, 1, 1)),
    19. ];
    20. // '("2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00")'
    21. Timeline.create({ range });

    无论怎样, 请注意无论何时你接收到的返回值将会是是一个范围:

    1. // 储存的值: ("2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00"]
    2. range // [Date, Date]
    3. range.inclusive // [false, true]

    确保在序列化之前将其转换为可序列化的格式,因为数组额外的属性将不会被序列化。

    特殊情况

    1. // 空范围:
    2. Timeline.create({ range: [] }); // range = 'empty'
    3. // 无限制范围:
    4. Timeline.create({ range: [null, null] }); // range = '[,)'
    5. // range = '[,"2016-01-01 00:00:00+00:00")'
    6. Timeline.create({ range: [null, new Date(Date.UTC(2016, 0, 1))] });
    7. // 无穷范围:
    8. // range = '[-infinity,"2016-01-01 00:00:00+00:00")'
    9. Timeline.create({ range: [-Infinity, new Date(Date.UTC(2016, 0, 1))] });

    可延迟

    1. // 将所有外键约束检查推迟到事务结束时。
    2. Sequelize.Deferrable.INITIALLY_DEFERRED
    3. // 立即检查外键约束。
    4. Sequelize.Deferrable.INITIALLY_IMMEDIATE
    5. // 不要推迟检查。
    6. Sequelize.Deferrable.NOT

    最后一个参数是 PostgreSQL 的默认值,不允许你在事务中动态的更改规则。 查看 the transaction section 获取补充信息.

    可以在模型上定义’对象属性’getter和setter函数,这些可以用于映射到数据库字段的“保护”属性,也可以用于定义“伪”属性。

    Getters和Setters可以通过两种方式定义(您可以混合使用这两种方式):

    • 作为属性定义的一部分
    • 作为模型参数的一部分

    注意: 如果在两个地方定义了getter或setter,那么在相关属性定义中找到的函数始终是优先的。

    定义为模型参数的一部分

    以下是在模型参数中定义 getter 和 setter 的示例。 fullName getter,是一个说明如何在模型上定义伪属性的例子 - 这些属性实际上不是数据库模式的一部分。 事实上,伪属性可以通过两种方式定义:使用模型getter,或者使用虚拟数据类型的列。 虚拟数据类型可以有验证,而虚拟属性的getter则不能。

    请注意,fullName getter函数中引用的this.firstnamethis.lastname将触发对相应getter函数的调用。 如果你不想那样使用getDataValue()方法来访问原始值(见下文)。

    1. const Foo = sequelize.define('foo', {
    2. firstname: Sequelize.STRING,
    3. lastname: Sequelize.STRING
    4. }, {
    5. getterMethods: {
    6. fullName() {
    7. return this.firstname + ' ' + this.lastname
    8. }
    9. },
    10. setterMethods: {
    11. fullName(value) {
    12. const names = value.split(' ');
    13. this.setDataValue('firstname', names.slice(0, -1).join(' '));
    14. this.setDataValue('lastname', names.slice(-1).join(' '));
    15. },
    16. }
    17. });
    • 检索底层属性值 - 总是使用 this.getDataValue()
    1. /* 一个用于 'title' 属性的 getter */
    2. get() {
    3. return this.getDataValue('title')
    4. }
    • 设置基础属性值 - 总是使用 this.setDataValue()
    1. /* 一个用于 'title' 属性的 setter */
    2. set(title) {
    3. this.setDataValue('title', title.toString().toLowerCase());
    4. }

    注意: 坚持使用 setDataValue()getDataValue() 函数(而不是直接访问底层的“数据值”属性)是非常重要的 - 这样做可以保护您的定制getter和setter不受底层模型实现的变化。

    验证

    模型验证,允许您为模型的每个属性指定格式/内容/继承验证。

    验证会自动运行在 createupdatesave 上。 你也可以调用 validate() 手动验证一个实例。

    验证由 validator.js 实现。

    1. const ValidateMe = sequelize.define('foo', {
    2. foo: {
    3. type: Sequelize.STRING,
    4. validate: {
    5. is: ["^[a-z]+$",'i'], // 只允许字母
    6. is: /^[a-z]+$/i, // 与上一个示例相同,使用了真正的正则表达式
    7. not: ["[a-z]",'i'], // 不允许字母
    8. isEmail: true, // 检查邮件格式 (foo@bar.com)
    9. isUrl: true, // 检查连接格式 (http://foo.com)
    10. isIP: true, // 检查 IPv4 (129.89.23.1) 或 IPv6 格式
    11. isIPv4: true, // 检查 IPv4 (129.89.23.1) 格式
    12. isIPv6: true, // 检查 IPv6 格式
    13. isAlpha: true, // 只允许字母
    14. isAlphanumeric: true, // 只允许使用字母数字
    15. isNumeric: true, // 只允许数字
    16. isInt: true, // 检查是否为有效整数
    17. isFloat: true, // 检查是否为有效浮点数
    18. isDecimal: true, // 检查是否为任意数字
    19. isLowercase: true, // 检查是否为小写
    20. isUppercase: true, // 检查是否为大写
    21. notNull: true, // 不允许为空
    22. isNull: true, // 只允许为空
    23. notEmpty: true, // 不允许空字符串
    24. equals: 'specific value', // 只允许一个特定值
    25. contains: 'foo', // 检查是否包含特定的子字符串
    26. notIn: [['foo', 'bar']], // 检查是否值不是其中之一
    27. isIn: [['foo', 'bar']], // 检查是否值是其中之一
    28. notContains: 'bar', // 不允许包含特定的子字符串
    29. len: [2,10], // 只允许长度在2到10之间的值
    30. isUUID: 4, // 只允许uuids
    31. isDate: true, // 只允许日期字符串
    32. isAfter: "2011-11-05", // 只允许在特定日期之后的日期字符串
    33. isBefore: "2011-11-05", // 只允许在特定日期之前的日期字符串
    34. max: 23, // 只允许值 <= 23
    35. min: 23, // 只允许值 >= 23
    36. isCreditCard: true, // 检查有效的信用卡号码
    37. // 也可以自定义验证:
    38. isEven(value) {
    39. if (parseInt(value) % 2 != 0) {
    40. throw new Error('Only even values are allowed!')
    41. // 我们也在模型的上下文中,所以如果它存在的话,
    42. // this.otherField会得到otherField的值。
    43. }
    44. }
    45. }
    46. }
    47. });

    请注意,如果需要将多个参数传递给内置的验证函数,则要传递的参数必须位于数组中。 但是,如果要传递单个数组参数,例如isIn的可接受字符串数组,则将被解释为多个字符串参数,而不是一个数组参数。 要解决这个问题,传递一个单一长度的参数数组,比如[['one','two']]

    要使用自定义错误消息而不是 validator.js 提供的错误消息,请使用对象而不是纯值或参数数组,例如不需要参数的验证器可以被给定自定义消息:

    1. isInt: {
    2. msg: "Must be an integer number of pennies"
    3. }

    或者如果还需要传递参数,请添加一个args属性:

    1. isIn: {
    2. args: [['en', 'zh']],
    3. msg: "Must be English or Chinese"
    4. }

    当使用自定义验证器函数时,错误消息将是抛出的Error对象所持有的任何消息。

    有关内置验证方法的更多详细信息,请参阅 。

    提示: 您还可以为日志记录部分定义自定义函数。 只是传递一个方法。 第一个参数将是记录的字符串。

    验证器 与 allowNull

    如果模型的特定字段设置为允许null(使用allowNull:true),并且该值已设置为null,则其验证器不会运行。 这意味着你可以有一个字符串字段来验证其长度至少为5个字符,但也允许null

    验证器也可以在特定字段验证器之后用来定义检查模型。例如,你可以确保纬度经度都不设置,或者两者都设置,如果设置了一个而另一个未设置则验证失败。

    模型验证器方法与模型对象的上下文一起调用,如果它们抛出错误,则认为失败,否则通过。 这与自定义字段特定的验证器一样。

    一个例子:

    1. const Pub = Sequelize.define('pub', {
    2. name: { type: Sequelize.STRING },
    3. address: { type: Sequelize.STRING },
    4. latitude: {
    5. type: Sequelize.INTEGER,
    6. allowNull: true,
    7. defaultValue: null,
    8. validate: { min: -90, max: 90 }
    9. },
    10. longitude: {
    11. type: Sequelize.INTEGER,
    12. allowNull: true,
    13. defaultValue: null,
    14. },
    15. }, {
    16. validate: {
    17. bothCoordsOrNone() {
    18. if ((this.latitude === null) !== (this.longitude === null)) {
    19. }
    20. }
    21. }
    22. })

    在这种简单情况下,如果给定纬度或经度,而不是同时包含两者,则验证失败。 如果我们尝试构建一个超范围的纬度和经度,那么raging_bullock_arms.validate()可能会返回

    1. {
    2. 'latitude': ['Invalid number: latitude'],
    3. 'bothCoordsOrNone': ['Require either both latitude and longitude or neither']
    4. }

    配置

    你还可以修改 Sequelize 处理列名称的方式:

    1. const Bar = sequelize.define('bar', { /* bla */ }, {
    2. // 不添加时间戳属性 (updatedAt, createdAt)
    3. timestamps: false,
    4. // 不删除数据库条目,但将新添加的属性deletedAt设置为当前日期(删除完成时)。
    5. // paranoid 只有在启用时间戳时才能工作
    6. paranoid: true,
    7. // 不使用驼峰样式自动添加属性,而是下划线样式,因此updatedAt将变为updated_at
    8. underscored: true,
    9. // 禁用修改表名; 默认情况下,sequelize将自动将所有传递的模型名称(define的第一个参数)转换为复数。 如果你不想这样,请设置以下内容
    10. freezeTableName: true,
    11. // 定义表的名称
    12. tableName: 'my_very_custom_table_name',
    13. // 启用乐观锁定。 启用时,sequelize将向模型添加版本计数属性,
    14. // 并在保存过时的实例时引发OptimisticLockingError错误。
    15. // 设置为true或具有要用于启用的属性名称的字符串。
    16. version: true
    17. })

    如果你希望sequelize处理时间戳,但只想要其中一部分,或者希望您的时间戳被称为别的东西,则可以单独覆盖每个列:

    1. const Foo = sequelize.define('foo', { /* bla */ }, {
    2. // 不要忘记启用时间戳!
    3. timestamps: true,
    4. // 我不想要 createdAt
    5. createdAt: false,
    6. // 我想 updateAt 实际上被称为 updateTimestamp
    7. updatedAt: 'updateTimestamp',
    8. // 并且希望 deletedA t被称为 destroyTime(请记住启用paranoid以使其工作)
    9. deletedAt: 'destroyTime',
    10. paranoid: true
    11. })

    您也可以更改数据库引擎,例如 变更到到MyISAM, 默认值是InnoDB。

    最后,您可以为MySQL和PG中的表指定注释

    1. const Person = sequelize.define('person', { /* attributes */ }, {
    2. comment: "I'm a table comment!"
    3. })

    您还可以使用import方法将模型定义存储在单个文件中。 返回的对象与导入文件的功能中定义的完全相同。 由于Sequelizev1:5.0的导入是被缓存的,所以当调用文件导入两次或更多次时,不会遇到问题。

    1. // 在你的服务器文件中 - 例如 app.js
    2. const Project = sequelize.import(__dirname + "/path/to/models/project")
    3. // 模型已经在 /path/to/models/project.js 中定义好
    4. // 你可能会注意到,DataTypes与上述相同
    5. module.exports = (sequelize, DataTypes) => {
    6. return sequelize.define("project", {
    7. name: DataTypes.STRING,
    8. description: DataTypes.TEXT
    9. })
    10. }

    import方法也可以接受回调作为参数。

    1. sequelize.import('project', (sequelize, DataTypes) => {
    2. return sequelize.define("project", {
    3. name: DataTypes.STRING,
    4. description: DataTypes.TEXT
    5. })
    6. })

    这个额外的功能也是有用的, 例如 Error: Cannot find module 被抛出,即使 /path/to/models/project 看起来是正确的。 一些框架,如 Meteor,重载 require,并给出“惊喜”的结果,如:

    1. Error: Cannot find module '/home/you/meteorApp/.meteor/local/build/programs/server/app/path/to/models/project.js'

    这通过传入Meteor的require版本来解决. 所以,虽然这可能会失败 …

    1. const AuthorModel = db.import('./path/to/models/project');

    … 这应该是成功的 …

    1. const AuthorModel = db.import('project', require('./path/to/models/project'));

    乐观锁定

    Sequelize 内置支持通过模型实例版本计数的乐观锁定。

    默认情况下禁用乐观锁定,可以通过在特定模型定义或全局模型配置中将version属性设置为true来启用。 有关详细信息,请参阅。

    乐观锁定允许并发访问模型记录以进行编辑,并防止冲突覆盖数据。 它通过检查另一个进程是否已经读取记录而进行更改,并在检测到冲突时抛出一个OptimisticLockError。

    数据库同步

    当开始一个新的项目时,你还不会有一个数据库结构,并且使用Sequelize你也不需要它。 只需指定您的模型结构,并让库完成其余操作。 目前支持的是创建和删除表:

    1. // 创建表:
    2. Project.sync()
    3. Task.sync()
    4. // 强制创建!
    5. Project.sync({force: true}) // 这将先丢弃表,然后重新创建它
    6. // 删除表:
    7. Project.drop()
    8. Task.drop()
    9. // 事件处理:
    10. Project.[sync|drop]().then(() => {
    11. // 好吧...一切都很好!
    12. }).catch(error => {
    13. // oooh,你输入了错误的数据库凭据?
    14. })

    因为同步和删除所有的表可能要写很多行,你也可以让Sequelize来为做这些:

    1. // 同步所有尚未在数据库中的模型
    2. sequelize.sync()
    3. // 强制同步所有模型
    4. sequelize.sync({force: true})
    5. // 删除所有表
    6. sequelize.drop()
    7. // 广播处理:
    8. sequelize.[sync|drop]().then(() => {
    9. // woot woot
    10. }).catch(error => {
    11. // whooops
    12. })

    因为.sync({ force: true })是具有破坏性的操作,可以使用match参数作为附加的安全检查。

    match参数可以通知Sequelize,以便在同步之前匹配正则表达式与数据库名称 - 在测试中使用force:true但不使用实时代码的情况下的安全检查。

    1. // 只有当数据库名称以'_test'结尾时,才会运行.sync()
    2. sequelize.sync({ force: true, match: /_test$/ });

    Sequelize 模型是ES6类。 您可以轻松添加自定义实例或类级别的方法。

    1. const User = sequelize.define('user', { firstname: Sequelize.STRING });
    2. // 添加一个类级别的方法
    3. User.classLevelMethod = function() {
    4. return 'foo';
    5. };
    6. // 添加实例级别方法
    7. User.prototype.instanceLevelMethod = function() {
    8. return 'bar';
    9. };

    索引

    Sequelize支持在 Model.sync()sequelize.sync 中创建的模型定义中添加索引。

    1. sequelize.define('user', {}, {
    2. indexes: [
    3. // 在 email 上创建一个唯一索引
    4. {
    5. unique: true,
    6. fields: ['email']
    7. },
    8. // 在使用 jsonb_path_ops 的 operator 数据上创建一个 gin 索引
    9. {
    10. fields: ['data'],
    11. using: 'gin',
    12. operator: 'jsonb_path_ops'
    13. },
    14. // 默认的索引名将是 [table]_[fields]
    15. // 创建多列局部索引
    16. {
    17. name: 'public_by_author',
    18. fields: ['author', 'status'],
    19. where: {
    20. status: 'public'
    21. }
    22. },
    23. // 具有有序字段的BTREE索引
    24. {
    25. name: 'title_index',
    26. method: 'BTREE',
    27. fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
    28. }
    29. ]