首页 文章

sequelize - 删除多行,然后批量插入

提问于
浏览
1

我需要根据3个字段从表中删除多行 . 这些字段不是关键列 . POST请求发送所有行 . Sequelize不支持基于列的批量删除 . 所以我正在运行一个forEach循环来删除,然后想要使用bulkCreate插入 .

但是我创建的自定义函数不存在“.then()” . 任何人都可以提出更好的方法 . 谢谢!

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

我想更新记录是否存在,如果不存在则插入 . 以下是我的代码:

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

        });
  });

}

我收到以下错误“未处理的拒绝错误:发送后无法设置标头” . 这是有道理的,因为响应已经发送 . 不确定如何对所有记录执行操作,然后发送响应 .

我更新了代码以返回每行的承诺,收集承诺并返回它们 . 这段代码工作正常 .

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

}

但是,我想确保错误得到妥善处理 . 我在插入过程中断开了数据库 . 它会为循环中的每个失败记录抛出以下错误:

未处理拒绝TimeoutError:ResourceRequest超时未处理拒绝SequelizeHostNotFoundError:无法连接到主机

不是决心,拒绝应该处理这个错误 . 我在这里错过了什么吗?

2 回答

  • 0

    要使用Sequelize删除记录,您使用的是正确的 . 它会根据您提供的条件删除记录,如下所示 . Sequelize documentation

    Model.destroy({
        where: {
            // criteria
        }
    })
    

    所以你使用for循环迭代列表并删除它 . 但是您的自定义函数(deleteRows)不支持.then,因此您遇到了删除记录的问题 .

    我建议你使用promise来使你的功能如下所示 . 它将返回解决或拒绝 . Promise Documentation

    deleteRows: function(rows){
      return new Promise(function(resolve, reject){
        rows.forEach((row) => {
          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");
              reject('Internal Server Error');
            }
    
            resolve(region);
          });
        });
      });
    }
    

    通过使用承诺,您可以使用.then为您的功能 . 具体如下

    deleteRows(req.body.rows).then(function(result){
      // your logic
    })
    

    类似的,您也可以使用promise来添加记录 .

    第二种方法:您也可以使用async await执行相同的操作async await documentation

    deleteRows: async function(rows) {
    
        var result = await rows.forEach((row) => {
            models.TABLE.destroy({
                    where: {
                        CNTRY_CD: row['CNTRY_CD'],
                        AREA_ID: row['AREA_ID'],
                        BUS_DT: row['BUS_DT']
                    }
                })
                .then((region, err) => {
                    return region
                });
        });
    
    }
    
  • 0

    对于错误:

    未处理的拒绝TimeoutError:ResourceRequest超时未处理的拒绝SequelizeHostNotFoundError:无法连接到主机

    这可能有助于您捕获Promise.all函数中的错误 . 你可以使用如下 .

    const a = Promise.resolve(1);
    const b = Promise.reject(new Error(2));
    const c = Promise.resolve(3);
    
    Promise.all([a, b, c].map(p => p.catch(e => e)))
      .then(results => console.log(results)) // 1,Error: 2,3
      .catch(e => console.log(e));
    

相关问题