I need to delete multiple rows from a table based on 3 fields. These fields are not the key columns. POST request sends all the rows. Sequelize does not support bulk delete based on columns. So I am running a forEach loop to delete and then want to insert using bulkCreate.
But ".then()" does not exist for the custom function I created. Can anybody suggest a better way of doing this. Thank you!
create: (req, res) => {
let deleteRows = (rows) => {
rows.forEach((row) => {
console.log("=============");
console.log(row);
console.log("=============");
models.TABLE.destroy({ where: {CNTRY_CD: row['CNTRY_CD'], AREA_ID: row['AREA_ID'], BUS_DT: row['BUS_DT']}})
.then((region, err) => {
if(err) {
console.log("I am here");
return res.status(500).json({ error: 'Internal Server Error' });
}
//res.status(200).json(region);
});
});
};
deleteRows(req.body.rows)
.then((err) => {
if(err) {
console.log("Instead I am here");
return res.status(500).json({ err: 'Internal Server Error' });
} else {
models.TABLE.bulkCreate(req.body.rows)
.then((rows, err) => {
if(err) {
return res.status(500).json({ err: 'Internal Server Error' });
} else {
return res.status(201).json(`${req.body.rows.length} rows successfully inserted!`);
}
})
.catch((err) => {
res.status(500).json(err);
});
}
});
}
I want to update the record if it exists and insert if it does not exist. Below is the code I have:
create: (req, res) => {
req.body.rows.forEach((row) => {
models.AFT_DC_AREA_DAY_AOP.findOne({
where: { CNTRY_CD: row['CNTRY_CD'], AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'], BUS_DT: row['BUS_DT'] },
individualHooks: true,
defaults: {
CNTRY_CD: row['CNTRY_CD'],
FSCL_YR_NUM: row['FSCL_YR_NUM'],
FSCL_PER_SID: row['FSCL_PER_SID'],
FSCL_WK_BEG_DT: row['FSCL_WK_BEG_DT'],
BUS_DT: row['BUS_DT'],
AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'],
AREA_AOP_SALES: row['AREA_AOP_SALES']
}}).then((data, err) => {
if(err) {
return res.status(500).json({ error: 'Internal Server Error' });
}
if(data) {
models.AFT_DC_AREA_DAY_AOP.update(
{
CNTRY_CD: row['CNTRY_CD'],
FSCL_YR_NUM: row['FSCL_YR_NUM'],
FSCL_PER_SID: row['FSCL_PER_SID'],
FSCL_WK_BEG_DT: row['FSCL_WK_BEG_DT'],
BUS_DT: row['BUS_DT'],
AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'],
AREA_AOP_SALES: row['AREA_AOP_SALES']
}, {
where: {
id: data.id
}
}).then((updateData, err) => {
if(err) {
return res.status(500).json({ error: 'Internal Server Error' });
}
res.status(200).json(updateData);
});
} else {
models.AFT_DC_AREA_DAY_AOP.create(
{
CNTRY_CD: row['CNTRY_CD'],
FSCL_YR_NUM: row['FSCL_YR_NUM'],
FSCL_PER_SID: row['FSCL_PER_SID'],
FSCL_WK_BEG_DT: row['FSCL_WK_BEG_DT'],
BUS_DT: row['BUS_DT'],
AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'],
AREA_AOP_SALES: row['AREA_AOP_SALES']
}).then((createData, err) => {
if(err) {
return res.status(500).json({ error: 'Internal Server Error' });
}
res.status(200).json(createData);
});
}
});
});
}
I get following error "Unhandled rejection Error: Can't set headers after they are sent." which makes sense, because the response has been sent. Not sure how to perform the actions for all records and then send the response.
I updated the code to return a promise for each row, collecting the promise and returning them. This code works fine.
create: (req, res) => {
let UpdateOrCreate= function(rows){
var promises = [];
rows.forEach((row) => {
promises.push(insert(row));
});
return Promise.all(promises);
}
let insert = function(row){
return new Promise((resolve,reject)=>{
var newPromise = models.TABLE.findOne({
where: { CNTRY_CD: row['CNTRY_CD'], AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'], BUS_DT: row['BUS_DT'] },
individualHooks: true,
defaults: {
CNTRY_CD: row['CNTRY_CD'],
FSCL_YR_NUM: row['FSCL_YR_NUM'],
FSCL_PER_SID: row['FSCL_PER_SID'],
FSCL_WK_BEG_DT: row['FSCL_WK_BEG_DT'],
BUS_DT: row['BUS_DT'],
AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'],
AREA_AOP_SALES: row['AREA_AOP_SALES']
}
}).then((data, err) => {
if(err) {
reject('Internal Server Error');
}
if(data) {
models.TABLE.update(
{
CNTRY_CD: row['CNTRY_CD'],
FSCL_YR_NUM: row['FSCL_YR_NUM'],
FSCL_PER_SID: row['FSCL_PER_SID'],
FSCL_WK_BEG_DT: row['FSCL_WK_BEG_DT'],
BUS_DT: row['BUS_DT'],
AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'],
AREA_AOP_SALES: row['AREA_AOP_SALES']
}, {
where: {
id:data['dataValues']['id']
}
}).then((updateData, err) => {
if(err) {
reject('Internal Server Error');
}
resolve(updateData);
});
} else {
models.TABLE.create(
{
CNTRY_CD: row['CNTRY_CD'],
FSCL_YR_NUM: row['FSCL_YR_NUM'],
FSCL_PER_SID: row['FSCL_PER_SID'],
FSCL_WK_BEG_DT: row['FSCL_WK_BEG_DT'],
BUS_DT: row['BUS_DT'],
AREA_ORG_LVL_ID: row['AREA_ORG_LVL_ID'],
AREA_AOP_SALES: row['AREA_AOP_SALES']
}).then((createData, err) => {
if(err) {
reject('Internal Server Error');
}
resolve(createData);
});
}
});
})
}
UpdateOrCreate(req.body.rows).then(function (result) {
console.log("%%%%%%%%%%%%%%%%%%%%%%%%");
console.log(result);
console.log("%%%%%%%%%%%%%%%%%%%%%%%%");
res.status(200).json(`${req.body.rows.length} rows successfully inserted!`);
}).catch(function (err) {
return res.status(500).json({ error: 'Internal Server Error' });
});
}
But, I want to ensure errors were handled properly. I disconnected the DB while the inserting was in progress. It throws following errors for each failed record in the loop:
Unhandled rejection TimeoutError: ResourceRequest timed out Unhandled rejection SequelizeHostNotFoundError: Failed to connect to host
Isn't the resolve, reject supposed to handle this error. Am I missing something here?