zoukankan      html  css  js  c++  java
  • Sequelize Upgrade to V5 or V6

    前言

    记录一下ORM Sequelize升级到v5的过程中涉及到的几个地方。
    升级v6和v5 差别不大。

    记录

    升级命令

    $ npm i sequelize@5
    

    操作符替换(Operator)

    • v4是v3与v5的过渡版本,到了v5版本 $ 操作符已经被删除

    • v5操作符将 $ 操作符替换为了 Op 操作符(eg. $or换为了Op.or)

    // index.js
    const Sequelize = require("sequelize");
    
    const db = {};
    db.sequelize = sequelize;
    db.Sequelize = Sequelize;
    db.Op = Sequelize.Op;
    module.exports = db;
    
    // file.js
    const models = require('./index');
    
    const where = {};
    // where.$or = [];
    where[models.Op.or] = [];
    
    • 升级时未减少修改可以将Op挂载到导出的models模块,全局替换修改即可

    格式化操作符

    • 当时用JSON.stringify()格式化where时,由于models.Op.or返回的是Symbol类型,所以格式化后会为空(表现为where Symbol属性条件丢失)
    • 通常这个错误很难被发现,也不会报错,但是当我们在include中引用这个格式化后的where且include的required属性设为true时,就会引发错误(原因就是全连接时条件为空),当然其他情况也可能发生错误。
    • 如果项目中设计到操作符格式化,可以考虑格式化前使用$操作符,格式化后,再将操作符转换为Symbol类型

    下划线标记(underscored)

    • 目前我测试的只对列起作用
    • 在初始化mysql时,可以使用underscored属性声明列为下划线格式,默认为驼峰格式
    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属性进行声明
    weekMark: {
         field: 'weekMark',
         type: DataTypes.STRING(20),
         allowNull: false
    }
    

    时间戳设置(timestamps)

    • v5默认使用驼峰命名

    • 文档中提到underscored可以适用于外键、列、时间戳,但我试的只有列起作用了 O.o

    • 在模型定义的options中可以设置createdAt和updatedAt来设置时间戳的命名

    "use strict";
    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'
            });
    };
    

    外键设置

    • 外键同样默认使用驼峰命名

    • 使用下划线命名时需要显式设置

    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字段避免

    • 也可以用原生语句替换

    总结

    • 只记录了部分升级过程的错误
  • 相关阅读:
    mysql explain用法和结果的含义
    heapset水平自动扩容
    dashboard安装
    对List集合中的对象进行按某个属性排序
    MySql查询当天、本周、本月、本季度、本年的数据
    三种List集合的遍历方式
    Date相关处理
    ubuntu-14.04.2-desktop使用方法
    PowerShell命令卸载Win10内置应用
    Windows下MySQL绿色版安装配置与使用
  • 原文地址:https://www.cnblogs.com/xpengp/p/12918601.html
Copyright © 2011-2022 走看看