如何解决节点/快速/序列化:数据类型VIRTUAL在db:migration
当使用sequelize-cli运行db:migration时,数据类型为Virtual的模型字段和直接从Sequelize手册直接复制的get方法会产生SQL语法错误。通过反复试验排除了文件中的其他任何可能的错误。
MySQL 5.7.31和带有Express 4.17.1和mysql2 2.1.0的Sequelize ^ 6.3.5。
我的迁移文件:
'use strict'
const { DataTypes } = require('sequelize')
module.exports = {
up: async (queryInterface,Sequelize) => {
await queryInterface.createTable('users',{
id: {
type: DataTypes.UUID,defaultValue: Sequelize.UUIDV4,primaryKey: true,allowNull: false,// constraint on mysql
unique: true,// constraint on mysql
validate: {
isUUID: {
args: 4,msg: 'User ID must be a UUID4 string.'
}
}
},firstName: {
type: DataTypes.STRING,required: true,notEmpty: true,validate: {
len: {
args: [2,90],msg: 'The first name must contain between 2 and 90 characters.'
}
}
},lastName: {
type: DataTypes.STRING,msg: 'The last name must contain between 2 and 90 characters.'
}
}
},// Code that breaks the migration process:
fullName: {
type: DataTypes.VIRTUAL,get() {
return `${this.firstName} ${this.lastName}`;
}
},// End code that breaks migration process
email: {
type: DataTypes.STRING,unique: true,validate: {
isEmail: {
args: [true],msg: 'Incorrect email format'
},isLowercase: {
args: [true],msg: 'Email address must be lowercase'
},len: {
args: [2,50],msg: 'The email address must have between 2 and 50 characters',},notEmpty: {
args: [true],msg: 'The email field can\'t be empty.'
},}
},password: {
type: DataTypes.STRING,validate: {
len: {
args: [8,99],msg: 'Your password must contain at least 8 characters.',msg: 'The password field cannot be empty.'
}
}
},resetPasswordToken: {
type: DataTypes.STRING
},resetPasswordExpire: {
type: DataTypes.INTEGER
},createdAt: {
type: DataTypes.DATE,allowNull: false
},updatedAt: {
type: DataTypes.DATE,deletedAt: {
type: DataTypes.DATE
}
},{
paranoid: true,tableName: 'users'
})
},down: async (queryInterface,Sequelize) => {
await queryInterface.dropTable('users');
}
};
在sequelize-cli db:migrate
之后的控制台输出:
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'VIRTUAL,`email` VARCHAR(255)
NOT NULL UNIQUE,`password` VARCHAR(255) NOT NULL,' at line 1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
etc.
如果从模型中删除了fullName
字段,则迁移成功运行。
fullName字段中的get()方法与手册(https://sequelize.org/master/manual/getters-setters-virtuals.html#virtual-fields)中的示例相同。
这变得特别有趣,因为Sequelize手册指出虚拟数据类型不会添加到数据库中-这是此功能的重点:
The VIRTUAL field does not cause a column in the table to exist.
In other words,the model above will not have a fullName column.
However,it will appear to have it!
环境:
- 后续版本:^ 6.3.5
- Node.js版本:12.18.3
- 操作系统:MacOS / Docker 19.03.13 build 4484c46d9d
- MySQL 5.7.31
- Express 4.17.1
- NPM软件包
mysql2
2.1.0版(适配器) - 序列化CLI 6.2.0
谢谢您的帮助。
解决方法
Virtuals 的存在是为了帮助您查询模型(例如,在您的 API 控制器中获取用户的全名)。由于它们不存在于数据库中,因此不应将它们作为迁移文件的一部分。
简而言之,您应该在模型定义中使用 VIRTUAL
,而不是在使用 queryInterface.createTable
方法的迁移文件中。
希望这能回答您的问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。