Sequelize "unique: true" making same unique key two times with different keyname - mysql

Test1: Adding "unique: true" in email attribute.
Test2: Adding "unique: {args: true, msg: "xxxxxx"}" in email attribute.
Using Sequelize: 4.7.5 & MySQL: 5.7.19
I'm expecting there will be one index for both the test cases.
But I'm getting two indexes for the Test1. Both indexes are having same column but different keyname.
Is it a bug or I'm doing anything wrong?
Try the following model defs.
Test1 = {
id: {
type: Sequelize.INTEGER.UNSIGNED,
primaryKey: true,
autoIncrement: true
},
emailId: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
validate: {
isEmail: {
args: true,
msg: 'Invalid email id.'
}
}
}
}
Test2 = {
id: {
type: Sequelize.INTEGER.UNSIGNED,
primaryKey: true,
autoIncrement: true
},
emailId: {
type: Sequelize.STRING,
unique: {
args: true,
msg: 'This email id is already registered.'
},
allowNull: false,
validate: {
isEmail: {
args: true,
msg: 'Invalid email id.'
}
}
}
}

Use string instead boolean.
I found my answer here: https://github.com/sequelize/sequelize/issues/6134
Normal index with string

Related

Sequelize: Insert failed to foreignKey column

I'm trying to insert data to my table with foreign keys from another table. The relationship is already successfully created. But when I try to insert data to the table, it always input null, and I already handle it with add allowNull: false. But still don't know how to input the value into the foreign key value inside table column.
This is my Product model:
{
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
price: {
type: DataTypes.DECIMAL,
allowNull: false,
validate: {
isNumeric: {
args: true,
msg: 'Wrong price format'
}
}
},
image: {
type: DataTypes.TEXT,
allowNull: false
}
},
{
sequelize,
paranoid: true,
modelName: 'product'
}
);
and this is my category model:
category.init(
{
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
image: {
type: DataTypes.TEXT,
allowNull: false
}
},
{
sequelize,
paranoid: true,
modelName: 'category'
}
);
and this is relationship between them
category.hasMany(product, {
foreignKey: {
name: 'categoryId',
allowNull: false
},
onDelete: 'CASCADE'
});
product.belongsTo(category, {
foreignKey: {
name: 'categoryId',
allowNull: false
},
onDelete: 'CASCADE'
});
and on inserting code using express, this is the code:
const product = {
name,
description,
price,
image,
businessCompanyId,
categoryId
};
await Product.create(product);
Any help will be great, thank you!
Add a field of categoryId in Product model like this:-
categoryId: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: "category",
key: "id"
}
},
I have not proper understanding of businessCompanyId but hope this will help you!

Auto-populated field in a Sequelize Model?

I'm creating a Model for a 'users' table in MySQL. Ideally I'd like to have a 'firstName' and 'lastName' field and a 'fullName' that would be the addition of the other 2.
Is it possible to have that programatically in the Model or do I have to take care of that at INSERT time ?
const User = sequelize.define("users", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
firstName: {
type: Sequelize.STRING(50),
allowNull: false,
},
lastName: {
type: Sequelize.STRING(50),
allowNull: false,
},
fullName: {
type: Sequelize.STRING(50),
allowNull: false,
// something that makes 'firstName' + ' ' + 'lastName' ❤️
},
email: {
type: Sequelize.INTEGER(30),
allowNull: false,
},
});
Virtual Colums are what you are looking for.
"Virtual" columns are columns that do not get saved in your database - they are calculated on the fly based on the values of other columns. They are helpful for saving space if there are values we want to use on our instances that can be easily calculated.
const User = sequelize.define("users", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
firstName: {
type: Sequelize.STRING(50),
allowNull: false,
},
lastName: {
type: Sequelize.STRING(50),
allowNull: false,
},
fullName: {
type: DataTypes.VIRTUAL,
get() {
return `${this.firstName} ${this.lastName}`;
}
},
email: {
type: Sequelize.INTEGER(30),
allowNull: false,
},
});
For more infromation see virtual fields.

sequelize posting NULL in database(MySql)

module.exports = function (sequelize, Sequelize) {
var User = sequelize.define('user', {
id: { autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER },
firstname: { type: Sequelize.STRING, notEmpty: true },
lastname: { type: Sequelize.STRING, notEmpty: true },
//username: { type: Sequelize.TEXT },
//about: { type: Sequelize.TEXT },
mobileno: { type: Sequelize.STRING },
email: { type: Sequelize.STRING, validate: { isEmail: true } },
password: { type: Sequelize.STRING, allowNull: false },
last_login: { type: Sequelize.DATE },
//status: { type: Sequelize.ENUM('active', 'inactive'), defaultValue: 'active' }
});
return User;
}
Everything else is posting fine but mobileno is being posted as null in database.
I tried setting mobile no as allowNull = false but that gives me an error.
I also tried changing string to text but that didn't help either...
this is the eroor after adding allowNull=false..
After checking the documentation your code is working normally.
// setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null. If you want to check that a value
// is not null before querying the DB, look at the validations section below.
title: { type: Sequelize.STRING, allowNull: false },
Before saving to the db, you need to validate your info to make sure that mobileno is not null. Once you have a value for mobileno you can save it to the db.
Your problems is in your data not in your sequelize model
Based on your question I think you send the empty value for mobileno field
About AllowNull parameter: when you will set the false it's means sequelize will return error if you will not pass parameter (which happens in your case)
By default AllowNull value is true
My suggestion is to check you data before insert query also when you will run create command using sequelize check console it's will show you insert into sql format

ValidationError: "column" is not allowed to be empty on null column

When trying to set passwordResetToken to null I get not allowed to be empty errors. If I manually run the query against the db, no trouble.
The full code to update user is as follows:
let user = await this.usersRepository.getById(userId);
// ...
const userData = {
encryptedPassword: await bcrypt.hash(
newPasswd,
Number(process.env.BCRYPT_ROUNDS)
),
passwordResetToken: null,
passwordResetExpires: null
};
user = await this.usersRepository.update(user.id, userData);
I have a model defined as such
const User = sequelize.define(
'user',
{
forename: DataTypes.STRING,
surname: DataTypes.STRING,
email: DataTypes.STRING,
encryptedPassword: DataTypes.STRING,
passwordResetToken: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
validate: {
notEmpty: false
}
},
passwordResetExpires: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
validate: {
isDate: true
}
}
},
{
classMethods: {
associate() {
// associations can be defined here
}
}
}
);
As you can see allowNull is true, defaultValue is null and validate: notEmpty set to false. What am I missing?
Using sequelize v4.42.0
Dialect 'mysql'
This was actually caused by another part of my validation by npm module structure.
I had to set empty to true in my schema like this:
passwordResetToken: {
type: String,
required: false,
empty: true
},

sequelize with postgres database not working after migration from mysql

I change MySQL databese into postgreSQL in sequelize. But After migration I have issue with upper and lowercase first letter in Table or Model...
Before my MySQL version was working properly but after migration I got error message:
500 SequelizeDatabaseError: relation "Users" does not exist
My User model:
module.exports = function(sequelize, Sequelize) {
var User = sequelize.define("User", {
// profile
userlevel: Sequelize.STRING,
restaurant: Sequelize.STRING,
access: Sequelize.STRING,
optionsid: Sequelize.STRING,
email: Sequelize.STRING,
name: Sequelize.STRING,
gender: Sequelize.STRING,
location: Sequelize.STRING,
website: Sequelize.STRING,
picture: Sequelize.STRING,
// Oauth
password: {
type: Sequelize.STRING,
set: function(v) {
var salt = bcrypt.genSaltSync(5);
var password = bcrypt.hashSync(v, salt);
return this.setDataValue('password', password);
}
},
.....
Migration file:
"use strict";
module.exports = {
up: function(migration, DataTypes, done) {
migration.createTable("users", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
userlevel: {
type: DataTypes.STRING,
defaultValue: '5'
},
restaurant: {
type: DataTypes.STRING,
defaultValue: ''
},
access: {
type: DataTypes.STRING,
defaultValue: '1'
},
optionsid: {
type: DataTypes.STRING,
defaultValue: ''
},
email: {
type: DataTypes.STRING,
allowNull: false
},
name: {
type: DataTypes.STRING,
defaultValue: ''
},
gender: {
type: DataTypes.STRING,
defaultValue: ''
},
location: {
type: DataTypes.STRING,
defaultValue: ''
},
website: {
type: DataTypes.STRING,
defaultValue: ''
},
picture: {
type: DataTypes.STRING,
defaultValue: ''
},
password: {
type: DataTypes.STRING
},
facebook: {
type: DataTypes.STRING
},
twitter: {
type: DataTypes.STRING
},
google: {
type: DataTypes.STRING
},
tokens: {
type: DataTypes.STRING
},
resetPasswordToken: {
type: DataTypes.STRING
},
resetPasswordExpires: {
type: DataTypes.DATE
},
createdAt: {
allowNull: false,
type: DataTypes.DATE
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE
}
}).done(done);
},
down: function(migration, DataTypes, done) {
migration.dropTable("users").done(done);
}
};
If I change first letter of table in postgreSQL to uppercase everything is working properly...
PostgreSQL folds the names of ordinary identifiers to lower case. So users, Users, and USERS all resolve to the identifier users.
Delimited identifiers are different. (Delimited identifiers are surrounded by double quotes.) The identifiers "users", "Users", and "USERS" are three different identifiers.
Your migration created the table "users". Sequelize is looking for the table "Users". (Delimited identifiers--two different tables.)
You should probably change the identifier in your migration to "Users". There are other ways, but this is the path of least resistance. If this is already in production, you might be better off writing another migration that renames "users" to "Users".