Related
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',
},
},
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.
Here is my problem:
Table WO -> sparepart_request -> sparepart.
A work order have several sparepart and sparepart can belong to several WO.
This is my code in wo.js (sequelize model)
models.sparepart.belongsToMany(models.wo, { as: 'SPWO', through: 'sparepart_request', foreignKey: 'codSparePart' });
This is my code in sparepart.js (sequelize model).
models.sparepart.belongsToMany(models.wo, { as: 'SPWO', through: 'sparepart_request', foreignKey: 'codSparePart' });
In sparepart_request there is nothing about associations. I've followed the next instructions Sequelize
In my query I have the next code:
exports.readDetailWO = function (req, res) {
models.wo.findAll({
attributes: ['codWO'], // attributes: ['id', 'codWO', 'codSparePart', 'quantity', 'date_request', 'date_reception', 'details', 'codUser', 'received'],
raw: true,
where: {
codWO: req.params.codWO
},
include: [{
model: models.sparepart,
attributes: ['codSparePart', 'name', 'description', 'codManufacturer', 'image_uri', 'stock'],
paranoid: false,
required: false,
as: 'SPWO'
}]
}).then(sparePart => {
if (!sparePart) {
res.status(404);
res.send({
success: false,
message: 'Spare Part not found. ' + req.params.codWO,
data: sparePart
});
} else if (sparePart) {
res.json({
success: true,
message: 'Spare Part found.',
data: sparePart
});
}
}).catch(function (error) {
logger.error(JSON.stringify(error));
res.json({
message: 'Query not successful and error has occured reading',
error: error,
stackError: error.stack
});
return res.status(500);
});
};
But the server's response (using PostMan) is the following:
{
"message": "Query not successful and error has occured reading",
"error": {
"name": "SequelizeEagerLoadingError"
},
"stackError": "SequelizeEagerLoadingError: sparepart is not associated to wo!\n
AS I have been able to read here that maybe the problem that is my primaryKeys are not name id, but now I can change these names...
Where is the problem? Thanks in advance for your help.
Model sparepart_request.js
module.exports = function (sequelize, DataTypes) {
var sparepart_request = sequelize.define('sparepart_request', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
codWo: {
type: DataTypes.STRING(20),
allowNull: false,
foreignKey: {
model: 'wo',
key: 'codWO'
}
},
codSparePart: {
type: DataTypes.STRING(30),
allowNull: false,
references: {
model: 'sparepart',
key: 'codSparePart'
}
},
quantity: {
type: DataTypes.FLOAT,
allowNull: true
},
date_request: {
type: DataTypes.DATEONLY,
allowNull: true
},
date_reception: {
type: DataTypes.DATEONLY,
allowNull: true
},
details: {
type: DataTypes.TEXT,
allowNull: true
},
codUser: {
type: DataTypes.STRING(20),
allowNull: false,
references: {
model: 'user',
key: 'codUser'
}
},
received: {
type: DataTypes.INTEGER(1),
allowNull: false
}
}, {
tableName: 'sparepart_request',
timestamps: false
});
/* sparepart_request.associate = function (models) {
models.sparepart_request.hasMany(models.sparepart, {foreignKey: 'codSparePart', targetKey: 'codSparePart'});
}; */
return sparepart_request;
};
Model wo.js:
/* jshint indent: 1 */
module.exports = function (sequelize, DataTypes) {
var wo = sequelize.define('wo', {
codWO: {
type: DataTypes.STRING(20),
allowNull: false,
primaryKey: true
},
codUser: {
type: DataTypes.STRING(20),
allowNull: false,
references: {
model: 'user',
key: 'codUser'
}
},
codOriginator: {
type: DataTypes.STRING(20),
allowNull: true,
references: {
model: 'user',
key: 'codUser'
}
},
capture_date: {
type: DataTypes.DATE,
allowNull: false
},
active: {
type: DataTypes.INTEGER(1),
allowNull: false
},
codType: {
type: DataTypes.CHAR(3),
allowNull: false,
references: {
model: 'type',
key: 'codType'
}
},
date: {
type: DataTypes.DATEONLY,
allowNull: false
},
title: {
type: DataTypes.STRING(255),
allowNull: true
},
date_finish: {
type: DataTypes.DATEONLY,
allowNull: true
},
codStatus: {
type: DataTypes.STRING(10),
allowNull: false,
references: {
model: 'status',
key: 'codStatus'
}
},
hours_planned: {
type: DataTypes.FLOAT,
allowNull: true
},
codElement: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'element',
key: 'codElement'
}
},
Security: {
type: DataTypes.INTEGER(1),
allowNull: true,
defaultValue: '0'
},
codEquipment: {
type: DataTypes.STRING(20),
allowNull: false,
references: {
model: 'equipment',
key: 'codEquipment'
}
},
codProject: {
type: DataTypes.INTEGER(11),
allowNull: false,
references: {
model: 'project',
key: 'id'
}
},
codTestRoom: {
type: DataTypes.STRING(10),
allowNull: false,
references: {
model: 'testroom',
key: 'codTestRoom'
}
}
}, {
tableName: 'wo',
timestamps: false
});
wo.associate = function (models) {
models.wo.belongsTo(models.wo_operation, {
as: 'wo_operation',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.belongsTo(models.dailyinfo_detail, {
as: 'dailyInfo',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.hasOne(models.wo_corrective, {
as: 'wo_corrective',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.hasOne(models.wo_preventive, {
as: 'wo_preventive',
foreignKey: {
name: 'codWO',
allowNull: false
},
targetKey: 'codWO'
});
models.wo.belongsToMany(models.sparepart_request, { as: 'WOSP', through: 'sparepart_request', foreignKey: 'codWO', otherKey: 'codSparePart' });
};
return wo;
};
Model sparepart.js
/* jshint indent: 1 */
module.exports = function (sequelize, DataTypes) {
var sparepart = sequelize.define('sparepart', {
codSparePart: {
type: DataTypes.STRING(30),
allowNull: false,
primaryKey: true,
references: {
model: 'sparepart_request',
key: 'codSparePart'
}
},
name: {
type: DataTypes.STRING(45),
allowNull: true
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
available: {
type: DataTypes.INTEGER(1),
allowNull: false,
defaultValue: '1'
},
codManufacturer: {
type: DataTypes.INTEGER(11),
allowNull: false,
references: {
model: 'manufacturer',
key: 'codManufacturer'
}
},
stock: {
type: DataTypes.INTEGER(10),
allowNull: true
},
image_uri: {
type: DataTypes.STRING(500),
allowNull: true
},
codProject: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'project',
key: 'id'
}
},
price: {
type: DataTypes.FLOAT,
allowNull: false
}
}, {
tableName: 'sparepart',
timestamps: false
});
sparepart.associate = function (models) {
models.sparepart.belongsTo(models.manufacturer, {
foreignKey: 'codManufacturer',
targetKey: 'codManufacturer'
});
models.sparepart.belongsToMany(models.wo, { as: 'SPWO', through: 'sparepart_request', foreignKey: 'codSparePart', otherKey: 'codWO' });
};
return sparepart;
};
Here you can find my code, the three models and the query. at the moment I'm using postman I don't have anything in the frontEnd.
Here is one solution:
Remove id from sparepart_request.
Include the next code in sparepart_request:
sparepart_request.associate = function (models) {
models.sparepart_request.hasMany(models.sparepart, {foreignKey: 'codSparePart', targetKey: 'codSparePart'});
models.sparepart_request.hasMany(models.wo, {foreignKey: 'codWO', targetKey: 'codWO'});
};
Is it the correct way to do?, Apparently it is working...
I am having trouble adding users to my boards model using sequelize. My associations are defined as follows:
module.exports = function(sequelize, DataTypes) {
var Board = sequelize.define("Board", {
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
len: [1]
}
},
favorited: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
}
});
Board.associate = function(models) {
Board.belongsTo(models.User, {
foreignKey: {
name: "OwnerId"
}
});
Board.belongsToMany(models.User, {
through: "UserBoards"
});
};
return Board;
};
And my user model:
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define("User", {
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
isAlphanumeric: true
}
},
email: {
type: DataTypes.STRING,
allowNull: false,
validate: {
isEmail: true
}
},
password: {
type: DataTypes.STRING,
allowNull: false
}
});
User.associate = function(models) {
User.belongsToMany(models.Board, {
through: "UserBoards"
});
};
return User;
};
Console logging Boards.prototype gives me the following:
Board {
_customGetters: {},
_customSetters: {},
validators: { name: { len: [Object] } },
_hasCustomGetters: 0,
_hasCustomSetters: 0,
rawAttributes:
{ id:
{ type: [Object],
allowNull: false,
primaryKey: true,
autoIncrement: true,
_autoGenerated: true,
Model: Board,
fieldName: 'id',
_modelAttribute: true,
field: 'id' },
name:
{ type: [Object],
allowNull: false,
validate: [Object],
Model: Board,
fieldName: 'name',
_modelAttribute: true,
field: 'name' },
favorited:
{ type: BOOLEAN {},
allowNull: false,
defaultValue: false,
Model: Board,
fieldName: 'favorited',
_modelAttribute: true,
field: 'favorited' },
createdAt:
{ type: [Object],
allowNull: false,
_autoGenerated: true,
Model: Board,
fieldName: 'createdAt',
_modelAttribute: true,
field: 'createdAt' },
updatedAt:
{ type: [Object],
allowNull: false,
_autoGenerated: true,
Model: Board,
fieldName: 'updatedAt',
_modelAttribute: true,
field: 'updatedAt' },
OwnerId:
{ name: 'OwnerId',
type: [Object],
allowNull: true,
references: [Object],
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
Model: Board,
fieldName: 'OwnerId',
_modelAttribute: true,
field: 'OwnerId' } },
attributes: [ 'id', 'name', 'favorited', 'createdAt', 'updatedAt', 'OwnerId' ],
_isAttribute: { [Function: memoized] cache: MapCache { size: 0, __data__: [Object] } },
getUser: [Function],
setUser: [Function],
createUser: [Function],
getUsers: [Function],
countUsers: [Function],
hasUser: [Function],
hasUsers: [Function],
setUsers: [Function],
addUser: [Function],
addUsers: [Function],
removeUser: [Function],
removeUsers: [Function] }
But when I try to runt he following in my routes it says that addUser/addUsers are not functions:
router.get("/boards/:id/users/:uid", function(req, res) {
var query = {};
if (req.params.id) {
query.id = req.params.id;
db.Board.findAll({
where: query
}).then(function(dbBoard) {
dbBoard.addUser(req.params.uid);
res.json(dbBoards);
});
}
});
Any help would be appreciated. Thank you.
Adding an association is instance specific. You have to call this method on a single instance of the Board model. For example:
const singleBoard = db.board.findOne({where: query};
const user = db.users.findOne({where: {id: parseInt(req.params.uid)});
singleBoard.addUser(user);
You can iterate through the array you get from querying through findAll if you have to do the same operation on multiple boards.
https://sequelize.org/master/manual/advanced-many-to-many.html
Recently I met some trouble when I was doing bulkCreate in Sequelize. I got the following error:
TypeError: Cannot read property 'set' of undefined
at results.forEach (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/lib/model.js:2357:27)
at Array.forEach (<anonymous>)
at QueryInterface.bulkInsert.then.results (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/lib/model.js:2356:21)
at tryCatcher (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/Users/mzd/Desktop/Shroogal/shroogal-dev/node_modules/sequelize/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5)
And this is my sequelize migration file:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('documentsInstruments', {
docid: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: 'docid'
},
iid: {
type: DataTypes.BIGINT,
allowNull: true,
references: {
model: 'EntityInstruments',
key: 'IID'
},
field: 'IID'
},
docType: {
type: DataTypes.STRING(45),
allowNull: true,
field: 'docType'
},
docPath: {
type: DataTypes.STRING(200),
allowNull: true,
field: 'docPath'
},
creationDate: {
type: DataTypes.DATE,
allowNull: true,
field: 'creationDate'
},
addlInfo: {
type: DataTypes.STRING(500),
allowNull: true,
field: 'addlInfo'
},
posLabel: {
type: DataTypes.STRING(45),
allowNull: true,
field: 'posLabel'
},
active: {
type: DataTypes.STRING(3),
allowNull: true,
defaultValue: 'Y',
field: 'active'
},
origFileName: {
type: DataTypes.STRING(400),
allowNull: true,
field: 'origFileName'
}
}, {
tableName: 'Documents_Instruments'
});
};
And this is my bulkCreate function:
if(obj.documents) {
let data = [];
obj.documents.forEach((v, i) => {
var d = {};
if(v.docid)
d.docid = v.docid;
if(obj.iid)
d.iid = obj.iid;
if(v.type)
d.docType = v.type;
if(v.filePath)
d.docPath = v.filePath;
if(v.date)
d.creationDate = v.date;
if(v.additionalDescription)
d.addlInfo = v.additionalDescription;
if(v.originalName)
d.origFileName = v.originalName;
data.push(d);
});
this.documentsInstruments
.bulkCreate(data, {
updateOnDuplicate: ['docType', 'docPath', 'creationDate', 'addlInfo', 'origFileName']
})
.then((d) => {
resolve(d);
})
.catch((err) => {
reject(err);
});
}
I check the source code(node_modules/sequelize/lib/model.js:2357:27) and try to print something for debugging, the instance[i] become undefine in this.QueryInterface.bulkInsert functions
I got same issue you had and I couldn't find out why that error raised too.
But When i upgrade sequelize library version from v4.4.2 to 4.11.0, and then that error doesn't show up anymore.
If your version is not latest, try upgrade version.