Sequelize Upgrade to V5 or V6
前言
记录一下ORM Sequelize升级到v5的过程中涉及到的几个地方。
升级v6和v5 差别不大。
记录
升级命令
| 1 | $ npm i sequelize@5 | 
操作符替换(Operator)
- v4是v3与v5的过渡版本,到了v5版本 $ 操作符已经被删除 
- v5操作符将 $ 操作符替换为了 Op 操作符(eg. $or换为了Op.or) - 1 
 2
 3
 4
 5
 6
 7
 8- // index.js 
 const Sequelize = require("sequelize");
 const db = {};
 db.sequelize = sequelize;
 db.Sequelize = Sequelize;
 db.Op = Sequelize.Op;
 module.exports = db;
| 1 | // file.js | 
- 升级时未减少修改可以将Op挂载到导出的models模块,全局替换修改即可
格式化操作符
- 当时用JSON.stringify()格式化where时,由于models.Op.or返回的是Symbol类型,所以格式化后会为空(表现为where Symbol属性条件丢失)
- 通常这个错误很难被发现,也不会报错,但是当我们在include中引用这个格式化后的where且include的required属性设为true时,就会引发错误(原因就是全连接时条件为空),当然其他情况也可能发生错误。
- 如果项目中设计到操作符格式化,可以考虑格式化前使用$操作符,格式化后,再将操作符转换为Symbol类型
下划线标记(underscored)
- 目前我测试的只对列起作用 
- 在初始化mysql时,可以使用underscored属性声明列为下划线格式,默认为驼峰格式 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20- const Sequelize = require("sequelize"); 
 const sequelize = new Sequelize(
 db,
 user,
 pass,
 {
 dialect: 'mysql',
 host,
 3306,
 define: {
 'underscored': true
 },
 pool: {
 max: 30,
 min: 1,
 idle: 30000
 },
 logging: env === 'development' ? console.log : false,
 benchmark: env === 'development' // 输出日志时打印时间
 });
- 如果表中部分列使用的是驼峰命名,可以使用field属性进行声明 - 1 
 2
 3
 4
 5- weekMark: { 
 field: 'weekMark',
 type: DataTypes.STRING(20),
 allowNull: false
 }
时间戳设置(timestamps)
- v5默认使用驼峰命名 
- 文档中提到underscored可以适用于外键、列、时间戳,但我试的只有列起作用了 O.o 
- 在模型定义的options中可以设置createdAt和updatedAt来设置时间戳的命名 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18- ; 
 module.exports = function (sequelize, DataTypes) {
 return sequelize.define(
 "ExpressConfig", {
 id: {
 type: DataTypes.INTEGER(),
 allowNull: false,
 primaryKey: true,
 autoIncrement: true
 }
 },{
 createdAt: 'created_at',
 updatedAt: 'updated_at',
 timestamps: true,
 freezeTableName:true,
 tableName:'User'
 });
 };
外键设置
- 外键同样默认使用驼峰命名 
- 使用下划线命名时需要显式设置 - 1 
 2
 3
 4- UserRole.hasMany(models.User, { 
 foreignKey: "role_id",
 sourceKey: "id"
 });
undefined
- 在插入数据时,若值为undefined时,会默认忽略该列,与V4无变化 
- 在查询数据时,若where条件的值为undefined时,会报错(V4中会默认为null) 
当列字段包含 $ 字符时
- v5中在生成sql语句试,会使用正则表达式**/$($|\w+)/g去查找替换,所以当列字段包含 $ 字符时,会匹配失败,导致执行更新插入操作时报错Named bind parameter “${match}” has no value in the given object.** 
- v6中虽然修复过此bug,但是只是不再匹配单词中间的 $,单词前边的的 $ 字符还是会匹配到 
- 为了不影响其它地方使用,可以考虑修改字段名并结合field字段避免 
- 也可以用原生语句替换 

总结
- 只记录了部分升级过程的错误
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 个人记录!
 评论


