ERROR: Cannot add foreign key constraint- - mysql

I wrote a nodejs app with mysql db and Sequalize as an ORM. Every things is ok. I define models and migration to create database and seeders. I want to create a product model that in this model i have two foreign keys: (categoryId & shopId).
when i was create migration files, I create shop model after product model. and this is create a problem for me. when i want to create table in database using "sequelize db:migrate" command i get this error:
ERROR: Cannot add foreign key constraint
I read this link and know this is not the reason for my problem.
but how can i resolve this bug? i try to define up and down as an async function but this error did not resolve.
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable(
'products', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
name: {
type: Sequelize.STRING(255),
allowNull: false,
},
description: {
type: Sequelize.STRING(1024),
allowNull: false,
},
price: {
type: Sequelize.FLOAT,
allowNull: false,
},
old_price: {
type: Sequelize.FLOAT,
allowNull: false,
},
type: {
type: Sequelize.STRING(255),
},
height: {
type: Sequelize.INTEGER,
},
width: {
type: Sequelize.INTEGER,
},
categoryId: {
type: Sequelize.INTEGER,
references: {
model: 'categories',
key: 'id',
},
},
shopId: {
type: Sequelize.INTEGER,
references: {
model: 'shops',
key: 'id',
},
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
},
),
down: (queryInterface, Sequelize) => queryInterface.dropTable('products'),
}

You're passing the model as string. You need to point to your class.
Try this:
categoryId: {
type: Sequelize.INTEGER,
references: {
model: categories,
key: 'id',
},
},

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!

Sequelize migration fails with errno: 150 "Foreign key constraint is incorrectly formed"

I've created a table using this migration:
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('articles', {
id: { type: Sequelize.INTEGER, primaryKey: true,autoIncrement: true },
title: { type: Sequelize.STRING },
content: { type: Sequelize.TEXT },
createdAt: {type:Sequelize.DataTypes.DATE},
updatedAt: {type:Sequelize.DataTypes.DATE}
},
);
Then, in a new migration, i'm trying to create another table, which will reference the first one:
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('comments', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
title: { type: Sequelize.STRING },
content: { type: Sequelize.TEXT },
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
articleId: {
type: Sequelize.INTEGER,
references: {
model: {
tableName: 'articles',
schema: 'schema'
},
key: 'id'
},
}
},
);
}
I get
errno: 150 "Foreign key constraint is incorrectly formed"
Tried making this association in various ways, as i saw on the internet- all with the same error.
What could be the problem here? I will mention that the first table(articles) already exists in the DB.
Solved: It seems there is a mistake in the documentation. The way to do it is:
articleId: {
type: Sequelize.INTEGER,
references: {
model:"articles",
key:"id"
},
}

Could not find migration method: up

I am unable to migrate my models to MySQL db. It's throwing me the below error:
Loaded configuration file "config\config.json".
Using environment "development".
(node:5828) [SEQUELIZE0004] DeprecationWarning: A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed.
== 20191218125700-mig_admin_roles: migrating =======
ERROR: Could not find migration method: up
models- admin_user.js
module.exports = (sequelize, DataTypes) => {
{
var admin_users = sequelize.define("adminUser", {
id: {
type: DataTypes.INTEGER(22),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: "id"
},
fname: {
type: DataTypes.STRING(20),
allowNull: false,
field: "fname"
},
lname: {
type: DataTypes.STRING(20),
allowNull: true,
field: "lname"
},
phoneNo: {
type: DataTypes.STRING(20),
allowNull: false,
field: "phoneNo"
},
emailId: {
type: DataTypes.STRING(20),
allowNull: false,
unique: true,
field: "emailId"
},
isActive: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: "0",
field: "isActive"
},
password: {
type: DataTypes.STRING(128),
allownull: false,
field: "password"
}
});
admin_users.associate = models => {
admin_users.hasMany(models.adminRole, {
foreignKey: "roleId"
});
};
return admin_users;
}
};
migration: mig-admin_user.js
"use strict";
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable("adminUser", {
id: {
type: Sequelize.INTEGER(22),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: "id"
},
fname: {
type: Sequelize.STRING(20),
allowNull: false,
field: "fname"
},
lname: {
type: Sequelize.STRING(20),
allowNull: true,
field: "lname"
},
phoneNo: {
type: Sequelize.STRING(20),
allowNull: false,
field: "phoneNo"
},
emailId: {
type: Sequelize.STRING(20),
allowNull: false,
unique: true,
field: "emailId"
},
isActive: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: "0",
field: "isActive"
},
password: {
type: Sequelize.STRING(128),
allownull: false,
field: "password"
}
});
},
down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
I tried looking for this particular error, but couldn't find anything.
could anyone please tell where i might be going wrong?
You need a .sequelizerc in the root of your project and it contains something like this :
module.exports = {
'config': 'database/config.js',
'migrations-path': 'database/migrations',
'seeders-path': 'database/seeders'
}
And you have to point where are your migrations been located.

sequelize error: missing index for constraint

20181005120552-create-order-detail.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('OrderDetails', {
orderDetailId: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
},
orderId: {
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
references: {
model: 'Orders',
key: 'orderId'
}
},
productName: {
type: Sequelize.STRING,
primaryKey: true,
allowNull: false,
},
count: {
type: Sequelize.INTEGER
},
orderDetailPrice: {
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
references: {
model: 'Orders',
key: 'totalPrice'
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('OrderDetails');
}
};
20181005120522-create-order
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface
.createTable('Orders', {
orderId: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
userId: {
type: Sequelize.STRING,
onDelete: 'CASCADE',
references: {
model: 'Users',
key: 'userId'
}
},
orderDate: {
type: Sequelize.DATE
},
totalPrice: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false,
},
orderState: {
type: Sequelize.STRING
},
shippingNumber: {
type: Sequelize.STRING
},
basicAddress: {
type: Sequelize.STRING
},
detailAddress: {
type: Sequelize.STRING
},
telNumber: {
type: Sequelize.INTEGER
},
phoneNumber: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Orders');
}
};
When i executed script sequelize db:migrate, previous migration is without errors executed. in this level it returns error. I don't know how can i resolve this problem i guess it has something wrong.
ERROR: Failed to add the foreign key
constraint. Missing index for
constraint 'orderdetails_ibfk_2' in
the referenced table 'orders'
This is error message. I wanna connect files OrderDetails.orderDetailPrice and Orders.totalPrice.
Thanks.
As reported here, it seems that Sequelize has some issues with references to composite keys.
However, by exploiting the Sequelize query execution you can workaround you problem. In you case you can perform the following mysql query:
ALTER TABLE `db_test`.`OrderDetails` ADD CONSTRAINT `fk_order_detailes_orders`
FOREIGN KEY (`orderId` , `orderDetailId`)
REFERENCES `db_test `.`orders`(`orderId` , `totalPrice`);
So your create-order-detail migration file becomes the following:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('OrderDetails', {
orderDetailId: {
type: Sequelize.INTEGER.UNSIGNED,
primaryKey: true,
allowNull: false,
autoIncrement: true,
},
orderId: {
type: Sequelize.INTEGER,
allowNull: false,
},
productName: {
type: Sequelize.STRING,
primaryKey: true,
allowNull: false,
},
count: {
type: Sequelize.INTEGER,
},
orderDetailPrice: {
type: Sequelize.INTEGER,
allowNull: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
})
.then(() => {
return queryInterface.sequelize.query('ALTER TABLE `OrderDetails` ADD ' +
'CONSTRAINT `fk_order_details_orders` FOREIGN KEY (`orderId`, `orderDetailPrice`) REFERENCES ' +
'Orders(`orderId`, `totalPrice`)');
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('OrderDetails', null);
},
};
Giordano,
I defined this way the code is below. Let me know why this code can be migrated? primary key and unique key both keys are written though..
create-order-detail.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('OrderDetails', {
(...),
productName: {
type: Sequelize.STRING,
primaryKey: true,
// allowNull: false
unique: true
},
count: {
type: Sequelize.INTEGER
},
orderDetailPrice: {
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
// references: {
// model: 'Orders',
// key: 'totalPrice'
// }
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
})
.then(() => {
queryInterface.addConstraint('OrderDetails', ['orderDetailPrice'], {
type: 'foreign key',
references: {
name: 'orderdetails_ibfk_2',
table: 'Orders',
field: 'totalPrice'
},
})
})
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('OrderDetails');
}
};

why model not fetching all attributes in table in sequelize

I have created model for my databse and then run migration it successfully created the table in database after this I create migration to add column to that existing table . When I run model.findall query it only gets the attributes that I created first time e.g here is my model file
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('ActiveUsers', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
username: {
type: Sequelize.STRING
},
name: {
type: Sequelize.STRING
},
socketId: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('ActiveUsers');
}
};
here is migration file to add column to this table
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
queryInterface.addColumn(
'ActiveUsers',
'Token',
{
type: Sequelize.STRING,
allowNull: false
}
)
},
down: (queryInterface, Sequelize) => {
}
};
here is table pic
it only gets the attributes that are present in model file i.e
username,name,socketId,updatedAt,createdAt
why it dont get the value of
token,status
here is my code
activeusers.findAll({raw:true}).then(Users=>{
console.log('online users')
})
The first file you wrote is not a model file, it is a migration file. If you want to select your new fields you should add them to your model file.
Your model file should look like this:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('activeUsers', {
id: {
type: DataTypes.STRING,
allowNull: false,
primaryKey: true,
unique: true
},
username: {
type: Sequelize.STRING
},
name: {
type: Sequelize.STRING
},
socketId: {
type: Sequelize.STRING
},
token: {
type: Sequelize.STRING
},
status: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
};
You can read more in Sequelize docs about how to add models to your project.
We have to add column fields to model file manually . then it will fetch that fields