【问题标题】:SequelizeJS allows UNIQUE field to be duplicatedSequelizeJS 允许复制 UNIQUE 字段
【发布时间】:2019-09-18 02:08:43
【问题描述】:

在我的网络应用程序(NodeJS + ExpressJS + SequelizeJS)中,我定义了模型用户:

let User = connection.define('user', {
    username: {
        type: Sequelize.STRING(40),
        unique: true,
        allowNull: false,
        validate: {
            notEmpty: true,
            min: 4,
        }
    },
    email: {
        type: Sequelize.STRING,
        unique: true,
        allowNull: false,
        notEmpty: true,
        validate: {
            isEmail: true
        }
    },
    password: {
        type: Sequelize.STRING,
        allowNull: false,
        notEmpty: true,
        validate: {
            min: 8,

        }
    },
    name: {
        type: Sequelize.STRING(50),
        validate: {
            min: 2
        }
    },
    surname: {
        type: Sequelize.STRING(50),
        validate: {
            min: 3
        }
    },
    bio: Sequelize.TEXT(140),
    lastLogin: Sequelize.DATE,
    dateJoined: Sequelize.DATE,
    active: {
        type: Sequelize.BOOLEAN,
        defaultValue: false
    }
});


我希望用户名和电子邮件都是唯一的,这样没有人可以重复使用现有的电子邮件或现有的用户名。 所以我对其进行了测试,我注意到构建的查询如下:

Executing (default): 
CREATE TABLE IF NOT EXISTS `user`(
`id` INTEGER PRIMARY KEY AUTOINCREMENT, 
`username` VARCHAR(40) NOT NULL UNIQUE,
`email` VARCHAR(255) NOT NULL UNIQUE,
`password` VARCHAR(255) NOT NULL,
`nome` VARCHAR(50),
`cognome` VARCHAR(50),
`bio` TEXT,
`lastLogin` DATETIME,
`dateJoined` DATETIME,
`active` TINYINT(1) DEFAULT0,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL);

查询看起来不错。 然后我决定每次我的节点服务器启动时都进行相同的插入查询(使用相同的用户名和电子邮件),以测试是否保留了 NOT NULL 约束。

User.create({
        username: 'MYUSERNAME',
        email: 'MYEMAIL@GMAIL.COM',
        password: 'MYPASSWORD'
    })
        .then(newUser => {
            console.log('Insertion OK, username:', newUser.username);
        })
        .catch(error => {
            console.log(error);
        });

每次我重新启动服务器时的控制台输出:

Insertion OK, username: MYUSERNAME

如果我检查数据库记录,在用户表中,我会在相同字段中看到具有相同数据的多行。

-----------------------------------------------
| Username   | Email             | Password   |
-----------------------------------------------
| MYUSERNAME | MYEMAIL@GMAIL.COM | MYPASSWORD |
-----------------------------------------------
| MYUSERNAME | MYEMAIL@GMAIL.COM | MYPASSWORD |
-----------------------------------------------
| MYUSERNAME | MYEMAIL@GMAIL.COM | MYPASSWORD |
-----------------------------------------------



为什么不保留 UNIQUE 约束?

我正在为数据库使用 sqlite3 文件。

【问题讨论】:

  • 如果查看实际使用的表的定义(在 sqlite3 shell 中打开数据库并运行.schema user),它是否具有唯一约束?您可能使用的是添加之前的旧版本(假设您从一开始就没有它们)。
  • 是的,我注意到使用 DBrowser for SQLite 用户名字段未设置为唯一。我手动将其设置为唯一,现在一切正常,但我该如何解决这个问题?正确构建查询后,我不应该再触摸数据库并手动更改内容...
  • Sqlite 有一种方法可以在数据库中存储版本号,许多 ORM 会根据预期版本检查它并调用升级函数,让您有机会根据需要创建或修改表(或者您可以手动完成)。不知道这将如何与您的工具链一起使用。

标签: node.js database sqlite constraints sequelize.js


【解决方案1】:

这是我解决相同问题的方法,更改用户模型的电子邮件对象

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

或者如果您想要自定义验证错误消息

email: {
        type: Sequelize.STRING,
        allowNull: false,
        notEmpty: true,
        validate: {
            isEmail: true
        },
        unique: {
           args: 'email',
           msg: 'The email is already taken!'
        }
    }

记住如果你有一个迁移文件,你应该在邮件对象中指定unique: true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2020-03-26
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多