Sequelize自动为NOT NULL列设置默认值

5

我目前在我的MySQL数据库上运行Sequelize.js代码,该数据库使用迁移创建。我有一个人员表,定义如下:

return queryInterface.createTable('Persons', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        unique: true,
        type: Sequelize.INTEGER
      },
      email: {
        allowNull: false,
        unique: true,
        type: Sequelize.STRING
      },
      firstName: {
        type: Sequelize.STRING
      },
      lastName: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });

最终生成的表格如下:

`Persons` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `firstName` varchar(255) DEFAULT NULL,
  `lastName` varchar(255) DEFAULT NULL,
  `createdAt` datetime NOT NULL,
  `updatedAt` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `email` (`email`)
)

当我使用Model.create({})向数据库添加条目时(括号内没有其他内容),会向数据库添加以下对象:
id  email   firstName   lastName    createdAt   updatedAt
1   ''      NULL        NULL        2019-05-21 15:33:13 2019-05-21 15:33:13

我在数据库中的每个非空列都有一个默认值(varchar为空字符串,布尔值为false,datetime为NOW())。

Sequelize.js文档指出:

将allowNull设置为false将向列添加NOT NULL,这意味着如果列为空,则在执行查询时会从DB中抛出错误。如果要在查询DB之前检查值是否不为空,请查看下面的验证部分。

title: { type: Sequelize.STRING, allowNull: false },

我想按照官方文档所述接收错误,但不知道我做错了什么。

3个回答

8

我解决了这个问题。

我必须在模型定义中添加allowNull。当我第一次尝试时,出现了一些声明问题,但是现在重新访问该问题后它起作用了,并且我可以得到正确的错误信息。

module.exports = (sequelize, DataTypes) => {
    const Persons = sequelize.define('Persons', {
        email: {
            type: DataTypes.STRING(100),
            allowNull: false
        },
        firstName: DataTypes.STRING(40),
        lastName: DataTypes.STRING(40)
    }, {});
    return Persons;
};

1
这种情况可能发生在两种情况下。
首先,如果您在定义模型后稍后输入了allowNull,则需要使用sync({force: true})重新同步表格。
其次,如果不提供诸如emailfirstName之类的属性给create(),那么allowNull将起作用。例如,create({email:'',firstName:''})将填充空值。但是,如果您执行create({email:''}),然后跳过firstName属性将导致验证错误。
如果您正在从HTML表单标记等处执行create(req.body),并且默认情况下,如果未传递任何值,则body中的emailfirstName字段设置为空字符串,则会输入空值。由于Sequelize不认为req.body对象中的空字符串值是null值,因此会出现此问题。
您可以通过向验证添加notEmpty: true来调整验证,以避免出现这种行为。
email: {
        allowNull: false,
        unique: true,
        type: Sequelize.STRING
        validate : {
           notEmpty: true
        }

或者您可以通过将allowNull放入类似下面的验证属性中进行以下小型黑客,这样它就可以工作了;)

 email: {
        unique: true,
        type: Sequelize.STRING
        validate : {
           allowNull: false
        }

希望我表达清楚了 :)

-1
如果您覆盖了默认值,您应该会收到以下错误提示:
      email: {
        allowNull: false,
        unique: true,
        defaultValue: null,
        type: Sequelize.STRING
      },

当我这样做时,在迁移过程中会出现错误,提示“'email' 的默认值无效”。 - Brammz
那很抱歉,这超出了我对该框架的了解范围。 - TheWildHealer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接