Sequelize 中文文档:从 v6 升级到 v7 的完整指南

Sequelize 中文文档:从 v6 升级到 v7 的完整指南

【免费下载链接】sequelize-docs-Zh-CN 【免费下载链接】sequelize-docs-Zh-CN 项目地址: https://gitcode.com/gh_mirrors/se/sequelize-docs-Zh-CN

前言:为什么需要升级到 Sequelize v7?

Sequelize v7 作为 v6 之后的下一个主要版本,带来了多项重大改进和优化。如果你正在使用 Sequelize v6,升级到 v7 可以获得以下核心优势:

  • 🚀 完整的 TypeScript 支持:v7 的主要代码库已完全迁移到 TypeScript
  • 📊 更好的性能优化:移除 Bluebird,全面使用原生 async/await
  • 🔧 更清晰的 API 设计:修复了 v6 中的一些不一致性
  • 🛡️ 更强的类型安全:直接从 TypeScript 源码生成类型定义
  • 🌐 更新的数据库支持:支持最新的数据库引擎版本

本文将为你提供从 Sequelize v6 升级到 v7 的完整指南,涵盖所有重大变更、迁移步骤和最佳实践。

升级前的准备工作

环境要求检查

首先确认你的环境满足 v7 的最低要求:

# 检查 Node.js 版本
node --version

# 检查当前 Sequelize 版本
npm list sequelize

v7 的环境要求:

组件最低版本推荐版本
Node.js12.0.0+14.17.0+
TypeScript4.5+4.8+
npm6.0.0+8.0.0+

备份现有项目

在开始升级前,务必进行完整备份:

# 备份 package.json
cp package.json package.json.backup

# 备份重要配置文件
cp -r config/ config_backup/

重大变更详解

1. Node.js 版本支持

v7 只支持与 ES 模块规范兼容的 Node.js 版本(12 及更高版本)。

mermaid

2. TypeScript 全面转换

v7 的主要代码库已完全迁移到 TypeScript,这意味着:

  • 手动类型声明已被删除
  • 所有类型现在直接从实际的 TypeScript 代码中检索
  • 类型定义更加准确和一致
类型定义变化对比
// v6 中的类型定义(手动声明)
type UserAttributes = {
  id: number;
  name: string;
};

type UserCreationAttributes = Optional<UserAttributes, 'id'>;

class User extends Model<UserAttributes, UserCreationAttributes> {
  declare id: number;
  declare name: string;
}

// v7 推荐的方式(自动推断)
import { InferAttributes, InferCreationAttributes, CreationOptional } from '@sequelize/core';

class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
  declare id: CreationOptional<number>;
  declare name: string;
}

3. ConnectionManager 变更

仅当你直接使用 ConnectionManager 时才会受到影响:

// v6 中的用法(已废弃)
sequelize.connectionManager.getConnection({ type: 'SELECT' });

// v7 的正确用法
sequelize.connectionManager.getConnection({ type: 'read' });

4. 内部方法调用行为变更

Model.findOneModel.findAll 的内部调用行为发生变化:

class User extends Model {
  static findOne() {
    throw new Error('Do not call findOne');
  }
}

// v6 中会抛出错误
// v7 中正常工作
User.findByPk(1);

5. Microsoft SQL Server 支持

v7 完全支持 MS SQL Server 2017(版本 14),符合微软的主流支持策略。

逐步升级指南

步骤 1:更新依赖

# 更新 Sequelize 核心包
npm install @sequelize/core@^7.0.0

# 更新数据库驱动(根据你的数据库选择)
npm install pg@^8.0.0 pg-hstore@^2.0.0      # PostgreSQL
npm install mysql2@^3.0.0                   # MySQL
npm install sqlite3@^5.0.0                  # SQLite
npm install tedious@^17.0.0                 # MSSQL

# 移除不再需要的包
npm uninstall bluebird cls-hooked

步骤 2:更新类型导入

// v6 的导入方式
import { Sequelize, Model, DataTypes } from 'sequelize';

// v7 的正确导入方式
import { Sequelize, Model, DataTypes } from '@sequelize/core';

步骤 3:模型定义迁移

基础模型迁移
// v6 模型定义
class User extends Model {
  public id!: number;
  public name!: string;
  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;
}

User.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  createdAt: DataTypes.DATE,
  updatedAt: DataTypes.DATE,
}, {
  sequelize,
  modelName: 'User',
});

// v7 改进的模型定义
class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
  declare id: CreationOptional<number>;
  declare name: string;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

User.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  // 时间戳字段可以省略配置,Sequelize 会自动处理
}, {
  sequelize,
  modelName: 'User',
  timestamps: true, // 明确启用时间戳
});
关联模型迁移
// v6 关联定义
Project.belongsTo(User, { foreignKey: 'userId' });
User.hasMany(Project, { foreignKey: 'userId' });

// v7 改进的关联定义(使用 ForeignKey 类型)
class Project extends Model<InferAttributes<Project>, InferCreationAttributes<Project>> {
  declare id: CreationOptional<number>;
  declare userId: ForeignKey<number>;
  declare name: string;
}

// 外键配置由关联方法处理,无需在 init 中重复配置
Project.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  // 注意:userId 不在 init 中配置,由 belongsTo 处理
}, { sequelize });

Project.belongsTo(User);

步骤 4:查询方法更新

// v6 中的查询方式
const users = await User.findAll({
  where: {
    name: {
      [Op.like]: '%John%'
    }
  }
});

// v7 中操作符的导入方式变化
import { Op } from '@sequelize/core';

const users = await User.findAll({
  where: {
    name: {
      [Op.like]: '%John%'
    }
  }
});

步骤 5:事务处理更新

// v6 中的事务处理
const transaction = await sequelize.transaction();
try {
  await User.create({ name: 'John' }, { transaction });
  await transaction.commit();
} catch (error) {
  await transaction.rollback();
}

// v7 中可以使用更简洁的自动事务
await sequelize.transaction(async (t) => {
  await User.create({ name: 'John' }, { transaction: t });
});

常见问题解决

问题 1:类型错误 "Property 'xxx' does not exist"

// 错误:Property 'createdAt' does not exist on type 'User'
const user = await User.findByPk(1);
console.log(user.createdAt);

// 解决方案:明确定义时间戳字段
class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
  declare id: CreationOptional<number>;
  declare name: string;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

问题 2:关联外键类型错误

// 错误:外键字段类型不匹配
class Project extends Model {
  declare userId: number; // 应该使用 ForeignKey 类型
}

// 正确做法
import { ForeignKey } from '@sequelize/core';

class Project extends Model<InferAttributes<Project>, InferCreationAttributes<Project>> {
  declare userId: ForeignKey<number>;
}

问题 3:自定义方法中的类型问题

// v6 中的自定义方法
class User extends Model {
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

// v7 中需要正确处理类型
class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
  declare firstName: string;
  declare lastName: string;
  
  getFullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
}

升级检查清单

使用以下检查清单确保升级完整:

检查项状态说明
✅ Node.js 版本 ≥ 12必需
✅ 更新 @sequelize/core 到 v7核心包更新
✅ 更新数据库驱动兼容性检查
✅ 修改类型导入路径从 'sequelize' 改为 '@sequelize/core'
✅ 模型使用 InferAttributes类型推断优化
✅ 外键使用 ForeignKey 类型关联类型安全
✅ 时间戳字段明确定义避免类型错误
✅ 操作符导入更新从 '@sequelize/core' 导入 Op
✅ 移除 Bluebird 相关代码完全使用原生 Promise
✅ 测试所有查询功能功能验证

性能优化建议

升级到 v7 后,可以进一步优化性能:

1. 启用预编译查询

const sequelize = new Sequelize({
  dialect: 'postgres',
  // 启用预编译查询缓存
  benchmark: true,
  logging: false,
  // 其他配置...
});

2. 连接池优化

const sequelize = new Sequelize({
  dialect: 'postgres',
  pool: {
    max: 20,
    min: 5,
    acquire: 30000,
    idle: 10000,
  },
});

3. 批量操作优化

// 使用 bulkCreate 进行批量插入
await User.bulkCreate(users, {
  validate: true,
  ignoreDuplicates: true,
});

总结

Sequelize v7 带来了显著的改进,特别是对 TypeScript 的全面支持使得类型安全达到了新的水平。虽然升级过程需要一些调整,但这些改进为长期的项目维护和开发效率带来了巨大价值。

记住升级的关键点:

  1. 环境准备:确保 Node.js ≥ 12
  2. 依赖更新:正确更新核心包和数据库驱动
  3. 类型迁移:使用 InferAttributes 和 InferCreationAttributes
  4. 关联优化:正确使用 ForeignKey 类型
  5. 全面测试:确保所有功能正常工作

通过本指南,你应该能够顺利完成从 Sequelize v6 到 v7 的升级,并享受新版本带来的所有优势。如果在升级过程中遇到问题,建议参考官方文档或社区资源。


下一步行动

  •  立即备份当前项目
  •  逐项完成升级检查清单
  •  在开发环境进行充分测试
  •  逐步部署到生产环境

祝你升级顺利! 🚀

【免费下载链接】sequelize-docs-Zh-CN 【免费下载链接】sequelize-docs-Zh-CN 项目地址: https://gitcode.com/gh_mirrors/se/sequelize-docs-Zh-CN

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值