模型定义
在 Sequelize 中可以用两种等效的方式定义模型:
- 调用 sequelize.define(modelName, attributes, options)
- 扩展 Model 并调用 init(attributes, options)
定义模型后,可通过其模型名称在 sequelize.models 中使用该模型。
使用 sequelize.define:
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('runoops_test', 'root', '123456', {
    host: 'localhost',
    dialect: 'mysql' /* 选择 'mysql' | 'mariadb' | 'postgres' | 'mssql' 其一 */
  });
const User = sequelize.define('User', {
  // 在这里定义模型属性
  firstName: {
    type: DataTypes.STRING,
    allowNull: false
  },
  lastName: {
    type: DataTypes.STRING
    // allowNull 默认为 true
  }
}, {
  // 这是其他模型参数
});
// `sequelize.define` 会返回模型
console.log(User === sequelize.models.User); // true扩展 Model
const { Sequelize, DataTypes, Model } = require('sequelize');
const sequelize = new Sequelize('runoops_test', 'root', '123456', {
    host: 'localhost',
    dialect: 'mysql' /* 选择 'mysql' | 'mariadb' | 'postgres' | 'mssql' 其一 */
  });
class User extends Model {}
User.init({
  // 在这里定义模型属性
  firstName: {
    type: DataTypes.STRING,
    allowNull: false
  },
  lastName: {
    type: DataTypes.STRING
    // allowNull 默认为 true
  }
}, {
  // 这是其他模型参数
  sequelize, // 我们需要传递连接实例
  modelName: 'User' // 我们需要选择模型名称
});
// 定义的模型是类本身
console.log(User === sequelize.models.User); // true在内部,sequelize.define 调用 Model.init,因此两种方法本质上是等效的。
公共类字段的注意事项
添加与模型属性之一同名的公共类字段会出现问题. Sequelize 为通过 Model.init 定义的每个属性添加一个 getter 和一个 setter. 添加公共类字段将隐藏那些 getter 和 setter,从而阻止对模型的实际数据的访问。
// 无效的
class User extends Model {
  id; // 此字段将影响 sequelize 的 getter 和 setter. 它应该被删除.
  otherPublicField; // 这个字段不会影响任何东西. 没问题.
}
User.init({
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true
  }
}, { sequelize });
const user = new User({ id: 1 });
user.id; // undefined
// 有效的
class User extends Model {
  otherPublicField;
}
User.init({
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true
  }
}, { sequelize });
const user = new User({ id: 1 });
user.id; // 1在 TypeScript 中, 您可以使用 declare 关键字添加键入信息, 而无需添加实际的公共类字段:
// 有效
class User extends Model {
  declare id: number; // 您可以使用 `declare` 关键字添加键入信息, 而无需添加实际的公共类字段.
}
User.init({
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true
  }
}, { sequelize });
const user = new User({ id: 1 });
user.id; // 1
表名推断
默认情况下,当未提供表名时,Sequelize 会自动将模型名复数并将其用作表名. 这种复数是通过称为 inflection 的库在后台完成的,因此可以正确计算不规则的复数(例如 person -> people)。
强制表名称等于模型名称
sequelize.define('User', {
  // ... (属性)
}, {
  freezeTableName: true
});上面的示例将创建一个名为 User 的模型,该模型指向一个也名为 User 的表.
也可以为 sequelize 实例全局定义此行为:
const sequelize = new Sequelize('runoops_test', 'root', '123456', {
    host: 'localhost',
    dialect: 'mysql' /* 选择 'mysql' | 'mariadb' | 'postgres' | 'mssql' 其一 */
    freezeTableName: true
  });这样,所有表将使用与模型名称相同的名称。
直接提供表名
你也可以直接告诉 Sequelize 表名称:
sequelize.define('User', {
  // ... (属性)
}, {
  tableName: 'Employees'
});模型同步
可以通过调用一个异步函数(返回一个Promise)model.sync(options)来实现模型同步(执行SQL)。
User.sync() - 如果表不存在,则创建该表(如果已经存在,则不执行任何操作)
User.sync({ force: true }) - 将创建表,如果表已经存在,则将其首先删除
User.sync({ alter: true }) - 这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型等),然后在表中进行必要的更改以使其与模型匹配.实例
await User.sync({ force: true });
console.log("用户模型表刚刚(重新)创建!");一次同步所有模型
你可以使用 sequelize.sync() 自动同步所有模型. 示例:
await sequelize.sync({ force: true });
console.log("所有模型均已成功同步.");同步的数据表users 结构如下:
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `firstName` varchar(255) NOT NULL,
  `lastName` varchar(255) DEFAULT NULL,
  `createdAt` datetime NOT NULL,
  `updatedAt` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;删除表
删除与模型相关的表:
await User.drop();
console.log("用户表已删除!");
删除所有表:
await sequelize.drop();
console.log("所有表已删除!");数据库安全检查
如上所示,sync和drop操作是破坏性的. Sequelize 使用 match 参数作为附加的安全检查,该检查将接受 RegExp:
// 仅当数据库名称以 '_test' 结尾时,它才会运行.sync()
sequelize.sync({ force: true, match: /_test$/ });
时间戳
默认情况下,Sequelize 使用数据类型 DataTypes.DATE 自动向每个模型添加 createdAt 和 updatedAt 字段。
对于带有 timestamps: false 参数的模型,可以禁用此行为:
sequelize.define('User', {
  // ... (属性)
}, {
  timestamps: false
});也可以只启用 createdAt/updatedAt 之一,并为这些列提供自定义名称:
class Foo extends Model {}
Foo.init({ /* 属性 */ }, {
  sequelize,
  // 不要忘记启用时间戳!
  timestamps: true,
  // 不想要 createdAt
  createdAt: false,
  // 想要 updatedAt 但是希望名称叫做 updateTimestamp
  updatedAt: 'updateTimestamp'
});
列声明简写语法
如果关于列的唯一指定内容是其数据类型,则可以缩短语法:
// 例如:
sequelize.define('User', {
  name: {
    type: DataTypes.STRING
  }
});
// 可以简写为:
sequelize.define('User', { name: DataTypes.STRING });
默认值
默认情况下,Sequelize 假定列的默认值为 NULL. 可以通过将特定的 defaultValue 传递给列定义来更改此行为:
sequelize.define('User', {
  name: {
    type: DataTypes.STRING,
    defaultValue: "John Doe"
  }
});
一些特殊的值,例如 DataTypes.NOW,也能被接受:
sequelize.define('Foo', {
  bar: {
    type: DataTypes.DATETIME,
    defaultValue: DataTypes.NOW
    // 这样,当前日期/时间将用于填充此列(在插入时)
  }
});
				 自学教程
自学教程
分享笔记