i am a fresher i need help on nodejs - mysql

i have three tables (questions , options , answers)
in these three table parent model is questions and then child is options and answers
so, i want to delete child data also calling by parent id
Here is questions models
import Sequelize from "sequelize";
import Exam from "../../models/exam.js";
import sequelize from "../../utilities/database.js";
const Question = sequelize.define("question", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
questiontext: {
type: Sequelize.STRING,
allowNull: true,
},
questiontexthindi: {
type: Sequelize.STRING,
allowNull: true,
},
questionImgURL: {
type: Sequelize.STRING,
allowNull: true,
},
description: {
type: Sequelize.TEXT,
allowNull: true,
},
examId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: Exam,
key: "id",
},
},
isActive: {
type: Sequelize.BOOLEAN,
defaultValue: true,
},
});
export default Question;
options models
import Sequelize from "sequelize";
import sequelize from "../../utilities/database.js";
import Question from "./question.js";
const Option = sequelize.define("option", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
optiontext: {
type: Sequelize.STRING,
// (Sequelize.STRING),
allowNull: false,
isLength: [2, 6],
},
questionId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: Question,
key: "id",
onDelete: "CASCADE",
},
},
isActive: {
type: Sequelize.BOOLEAN,
defaultValue: true,
},
});
export default Option;
Here is answers models
import Sequelize from "sequelize";
import sequelize from "../../utilities/database.js";
import Question from "./question.js";
import Option from "./option.js";
const Answer = sequelize.define("answer", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
questionId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: Question,
key: "id",
onDelete: "CASCADE",
},
},
optionId: {
type: Sequelize.INTEGER,
allowNull: true,
references: {
model: Option,
key: "id",
},
},
correctanswer: {
type: Sequelize.STRING,
allowNull: false,
},
isActive: {
type: Sequelize.BOOLEAN,
defaultValue: true,
},
});
export default Answer;
Here is my controller
//models
import Question from "../../../models/model-tesportal/option.js";
//helpers
import { validationErrorHandler } from "../../../helpers/validation-error-handler.js";
export const deleteTestSeries = async (req, res, next) => {
validationErrorHandler(req, next);
const questionId = req.params.questionId;
try {
const result = await Question.destroy({
where: {
questionId: questionId,
},
});
if (result[0] === 0) {
const error = new Error("Question not found");
error.statusCode = 404;
return next(error);
}
res.status(201).json({
message: "Question Deleted successfully",
});
} catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};
i want to pass questionId in params and then delete data of that particular questionId will be deleted from parent and child tables

I got the solution from #geeks for geeks
i have to modify in my models where i wanna access those reference key Id
just look at my models now it works perfectly :
here is questions model {parent}
import Sequelize from "sequelize";
import Exam from "../../models/exam.js";
import sequelize from "../../utilities/database.js";
const Question = sequelize.define("question", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: "id", **<----- modify here**
},
questiontext: {
type: Sequelize.STRING,
allowNull: true,
},
questiontexthindi: {
type: Sequelize.STRING,
allowNull: true,
},
questionImgURL: {
type: Sequelize.STRING,
allowNull: true,
},
description: {
type: Sequelize.TEXT,
allowNull: true,
},
examId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: Exam,
key: "id",
},
},
isActive: {
type: Sequelize.BOOLEAN,
defaultValue: true,
},
});
export default Question;
child - options model
import Sequelize from "sequelize";
import sequelize from "../../utilities/database.js";
import Question from "./question.js";
const Option = sequelize.define("option", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
optiontext: {
type: Sequelize.STRING,
// (Sequelize.STRING),
allowNull: false,
isLength: [2, 6],
},
questionId: {
type: Sequelize.INTEGER,
allowNull: false,
onDelete: "CASCADE", **<----- modify here**
references: {
model: Question,
key: "id",
FOREIGNKEY: "id", **<----- modify here**
},
},
isActive: {
type: Sequelize.BOOLEAN,
defaultValue: true,
},
});
export default Option;
child - answers models
import Sequelize from "sequelize";
import sequelize from "../../utilities/database.js";
import Question from "./question.js";
import Option from "./option.js";
const Answer = sequelize.define("answer", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
questionId: {
type: Sequelize.INTEGER,
allowNull: false,
onDelete: "CASCADE", **<----- modify here**
references: {
model: Question,
key: "id",
FOREIGNKEY: "id", **<----- modify here**
},
},
optionId: {
type: Sequelize.INTEGER,
allowNull: true,
references: {
model: Option,
key: "id",
},
},
correctanswer: {
type: Sequelize.STRING,
allowNull: false,
},
isActive: {
type: Sequelize.BOOLEAN,
defaultValue: true,
},
});
export default Answer;
main code controller
//models
import Question from "../../../models/model-tesportal/question.js";
//helpers
import { validationErrorHandler } from "../../../helpers/validation-error-handler.js";
export const deleteTestSeries = async (req, res, next) => {
validationErrorHandler(req, next);
try {
const result = await Question.destroy({
where: {
id: req.params.questionId,
},
});
if (result[0] === 0) {
const error = new Error("Question not found");
error.statusCode = 404;
return next(error);
}
res.status(201).json({
message: "Hey Admin Question Deleted successfully",
});
} catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};

Related

Sequelize Model exports a Function

i have define this model:
const Sequelize = require('sequelize');
const db = require("../database/db")
var Reparacion = db.sequelize.define('reparaciones', {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
descripcion: {
type: Sequelize.STRING(255),
allowNull: true
},
fecha_inicio: {
type: Sequelize.DATEONLY,
allowNull: true
},
fecha_fin: {
type: Sequelize.DATEONLY,
allowNull: true
},
},{});
module.exports=Reparacion
In other model when I define the foreing Key in other model, the methods HasMany and belongsTo doesn't works because I call them on a function:
const Reparacion = require("./reparacion")
console.log(typeof(Vehiculo))
console.log(typeof(Reparacion))
Vehiculo.hasMany(Reparacion,{foreingKey:"vehiculoId", onDelete: 'cascade', sourceKey:"matricula"})
Reparacion.belongsTo(Vehiculo)
The both console log return: "function"
What i have to change for define correctly the association??
EDIT
that is de "Vehiculo" model:
const Sequelize = require('sequelize');
const db = require("../database/db")
var Vehiculo = db.sequelize.define('vehiculos', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: true
},
matricula: {
type: Sequelize.STRING(45),
allowNull: false,
primaryKey: true,
},
marca: {
type: Sequelize.STRING(50),
allowNull: true
},
modelo: {
type: Sequelize.STRING(50),
allowNull: true
},
anio: {
type: Sequelize.INTEGER,
allowNull: true
},
color: {
type: Sequelize.STRING(20),
allowNull: true
},
puertas: {
type: Sequelize.INTEGER,
allowNull: true
},
motor: {
type: Sequelize.STRING(20),
allowNull: true
},
},{});
const Reparacion = require("./reparacion")
Vehiculo.hasMany(Reparacion,{foreingKey:"vehiculoMatricula", onDelete: 'cascade', sourceKey:"matricula"})
Reparacion.belongsTo(Vehiculo)
module.exports=Vehiculo
Well, it is expected that typeof Vehiculo and typeof Reparacion will return a function that happens because every constructor or class is a function in JS, so when you create a model for an entity it returns a function/constructor that can create an instance of an entity for you. So there is no problem with that.
And actually the documentation shows similar code https://sequelize.org/master/manual/assocs.html

Set one-to-one association in sequelize

I am trying to get a single one-to-one association. This is my code:
Provider code
const Provider = sequelize.define("provider", {
idProvider: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
},
idUser: {
type: Sequelize.INTEGER,
primaryKey: true,
//unique: true,
},
isPublicProvider: {
type: Sequelize.BOOLEAN,
},
});
Provider.associate = function (models) {
Provider.hasOne(models.user, {
through: "users",
as: "idUser",
foreignKey: "idUser",
onDelete: "CASCADE",
});
};
In the association part, I have to get one IdUser only from this table
User code
const User = sequelize.define("user", {
idUser: {
type: Sequelize.INTEGER,
autoIncrement: true,
unique: true,
primaryKey: true,
},
nameUser: {
type: Sequelize.STRING,
validate: { notEmpty: true },
},
emailUser: {
type: Sequelize.STRING,
unique: true,
validate: { isEmail: true },
},
activeUser: {
type: Sequelize.BOOLEAN,
},
});
User.associate = (model) => {
User.belongsTo(models.Group, {
through: "providers",
as: "idUser",
foreignKey: "idUser",
});
};
When I check the ERR model, there is no relation between
[This is a image from my diagram] https://i.stack.imgur.com/bWqOo.png
Thanks to all before answer :)

How to populate table with foreign key values, using sequelize?

I have models: Business, Contributor, Feedback.
I have created relationship between Feedback and Contributor, and Feedback and Business like this:
Feedback.belongsTo(Business)
Feedback.belongsTo(Contributor)
The corresponding foreign key attributes are added to the table Feedback. Question is, how to populate them with IDs coming from Business and Contributor table records?
This approach only gets the first record. If I use findAll(), then I get undefined.
for (let assetsUrl of assetUrls) {
...
var businesses = null;
var reviews = null;
...
var timestamp = Math.floor(Date.now() / 1000);
var b_id = await Business.findOne({
attributes: ["id"],
})
var c_id = await Contributor.findOne({
})
businesses = await Business.upsert({
...
last_scraped: timestamp
});
reviews = await Review.upsert(
{
contributor_id: c_id.id,
business_id: b_id.id,
last_scraped: timestamp,
},
)
}
Business model:
class Business extends Model {}
Business.init(
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
site: {
type: Sequelize.STRING,
},
name: {
type: Sequelize.STRING,
},
business_type: {
type: Sequelize.STRING,
unique: false,
defaultValue: "",
},
address: {
type: Sequelize.TEXT,
// allowNull defaults to true
},
price: {
type: Sequelize.STRING,
},
url: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
last_scraped: {
type: Sequelize.INTEGER,
defaultValue: Math.floor(Date.now() / 1000)
},
},
{
sequelize,
modelName: "business",
timestamps: true,
createdAt: false,
updatedAt: false,
underscored: true
}
);
Business === sequelize.models.Business;
Business.sync();
Contributor model:
class Contributor extends Model {}
Contributor.init(
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
site: {
type: Sequelize.STRING,
},
name: {
type: Sequelize.STRING,
unique: false,
},
location: {
type: Sequelize.STRING,
unique: false,
},
photo: {
type: Sequelize.STRING,
unique: false,
},
url: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
status: {
type: Sequelize.SMALLINT,
},
last_scraped: {
type: Sequelize.INTEGER,
defaultValue: Math.floor(Date.now() / 1000)
},
},
{
sequelize,
modelName: "contributor",
timestamps: true,
createdAt: false,
updatedAt: false,
underscored: true,
}
);
Contributor === sequelize.models.Contributor;
Contributor.sync();
Feedback model:
class Feedback extends Model {}
Feedback.init(
{
contributor_id: {
type: Sequelize.INTEGER,
},
business_id: {
type: Sequelize.INTEGER,
},
date: {
type: Sequelize.STRING,
unique: false,
},
rating: {
type: Sequelize.STRING,
unique: false,
},
content: {
type: Sequelize.STRING,
unique: false,
},
last_scraped: {
type: Sequelize.INTEGER,
defaultValue: Math.floor(Date.now() / 1000)
},
},
{
sequelize,
modelName: "feedback",
timestamps: true,
createdAt: false,
updatedAt: false,
underscored: true,
}
);
Feedback.belongsTo(Contributor, { foreignKey: 'contributor_id' })
Feedback.belongsTo(Business, { foreignKey: 'business_id'})
Feedback=== sequelize.models.Review;
Feedback.sync();
A Good use case for model streaming but I think sequelize doesn't
support it yet
With your approch, using findOne combined with offset option you can
create/update the Feedback model like this.
// Get number of records to avoid unnecessary findOne in the loop
const bRecordCount = await Business.count();
const cRecordCount = await Contributor.count();
for (let i = 0; i < assetUrls.length; i++) {
const assetsUrl = assetUrls[i];
// ...
let bRecord = null;
let cRecord = null;
let options = {
attributes: ["id"],
// order by id to be sure we get different record each time
order: [['id', 'ASC']],
raw: true,
offset: i //skip already taken records
};
try {
if (i < bRecordCount && i < cRecordCount) {
bRecord = await Business.findOne(options)
cRecord = await Contributor.findOne(options)
}
if (bRecord && cRecord) {
feedback = await Feedback.upsert({
contributor_id: cRecord.id,
business_id: bRecord.id,
last_scraped: timestamp,
//...
});
}
} catch (err) {
console.log(err);
}
}
If you have many records you should consider using
findAll()
with offset and limit options,
then do a bulkCreate()
with updateOnDuplicate option to avoid making many database queries
To get Feedback items with certain attributes call findAll:
var feedback = await Feedback.findAll({
attributes: ['contributor_id', 'business_id', 'last_scraped']
})

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');
}
};