如何创建序列化事务以保存Deeplu Nest对象

时间:2020-05-20 16:27:37

标签: javascript transactions sequelize.js

如果我有一个这样的对象要保存:

{
    "objA": {
        "attr1": 123,
        "attr2": "dummy str",
   },
   "objB": [
        {
            "attr1": true,
            "attr2": [ // this a list of objC's
                {"attr1": 123, "attr2": false},
                {"attr1": 456, "attr2": true},
            ]
        },
        {
            "attr1": false,
            "attr2": [ // this a list of objC's
                {"attr1": 789, "attr2": true},
                {"attr1": 101, "attr2": true},
            ]
        },
    ]
}

关系如下:

  1. objA hasMany objB
  2. objB属于objA
  3. objB hasMany objC
  4. objC属于objB

在这一点上,Sequelize文档太浅,仅显示了如何保存一个简单的对象。所以这就是我一直没有成功尝试的事情:

const {objA, objB} = req.body;

return db.sequelize.transaction((t) => {
  return objA.create(
    {
      attr1,
      attr2,
      index,
    },
    { transaction: t }
  ).then((newObjA) => {      
    objB.forEach((obj) => {
      return objB.create(
        { ...obj, objA_id: newObjA.id },
        { transaction: t }
      ).then((newObjB) => {            
        objB.attr2.forEach((obj) => {
          return objC.create(
            { ...obj, objB_id: newObjB.id },
            { transaction: t }
            ).then((newObjC) => {
              return newObjB.addObjC(newObjC, {
                transaction: t,
              }).then(() => {
                  return newObjA.addObjB(newObjB);
              });
            });
          });
        });
      });
    });
  }).then(() => {
    res.status(200).json({ MSG: "SAVE_SUCCESS" });
  }).catch((err) => {
    res.status(500).json({ MSG: "SAVE_ERROR" });
});

1 个答案:

答案 0 :(得分:1)

您不应将forEach与异步功能一起使用(forEach用于同步迭代)。像这样使用 for await

// assuming ObjA, ObjB, ObjC are registered sequelize models
return db.sequelize.transaction(async t => {
  const newObjA = await ObjA.create(
    {
      attr1,
      attr2,
      index,
    },
    { transaction: t })
  for (const obj of objB) {
    const newObjB = await ObjB.create(
        { ...obj, objA_id: newObjA.id },
        { transaction: t })
    for (const attr of newObjB.attr2) {
      const newObjC = await ObjC.create(
            { ...attr, objB_id: newObjB.id },
            { transaction: t })
      await newObjB.addObjC(newObjC, {
                transaction: t,
              })
    }
    // you forgot to indicate transaction here in the original code
    await newObjA.addObjB(newObjB, { transaction: t }) 
  }
})