创建或更新Sequelize

Create or Update Sequelize

我在我的 Nodejs 项目中使用 Sequelize,我发现了一个我很难解决的问题。

基本上我有一个 cron 从服务器获取对象数组,然后将其作为对象插入到我的数据库中(对于这种情况,卡通)。但如果我已经拥有其中一个对象,我必须对其进行更新。

基本上我有一个对象数组,并且可以使用 BulkCreate() 方法。但是当 Cron 再次启动时,它并没有解决它,所以我需要一些带有 upsert true 标志的更新。主要问题是:在所有这些创建或更新之后,我必须有一个只触发一次的回调。有谁知道我该怎么做?迭代一个对象数组..创建或更新它,然后在之后获得一个回调?

感谢关注


从文档中,您无需查询 where 即可在拥有对象后执行更新。此外,promise 的使用应该简化回调:

实施

function upsert(values, condition) {

  return Model

    .findOne({ where: condition })

    .then(function(obj) {

      // updateif(obj)

        return obj.update(values);

      // insert

      return Model.create(values);

    })

}
upsert({ first_name: 'Taku' }, { id: 1234 }).then(function(result){

  res.status(200).send({success: true});

});
async function updateOrCreate (model, where, newItem) {

  // First try to find the record

 const foundItem = await model.findOne({where});

 if (!foundItem) {

    // Item not found, create a new one

    const item = await model.create(newItem)

    return {item, created: true};

  }

  // Found an item, update it

  const item = await model.update(newItem, {where});

  return {item, created: false};

}

function updateOrCreate (model, where, newItem) {

  // First try to find the record

  return model

  .findOne({where: where})

  .then(function (foundItem) {

    if (!foundItem) {

      // Item not found, create a new one

      return model

        .create(newItem)

        .then(function (item) { return {item: item, created: true}; })

    }

    // Found an item, update it

    return model

      .update(newItem, {where: where})

      .then(function (item) { return {item: item, created: false} }) ;

  }

}
updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})

  .then(function(result) {

    result.item; // the model

    result.created; // bool, if a new item was created.

  });
updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})

  .then(..)

  .catch(function(err){});
var updateOrCreate = function (model, where, newItem, onCreate, onUpdate, onError) {

  // First try to find the record

  model.findOne({where: where}).then(function (foundItem) {

    if (!foundItem) {

      // Item not found, create a new one

      model.create(newItem)

        .then(onCreate)

        .catch(onError);

    } else {

      // Found an item, update it

      model.update(newItem, {where: where})

        .then(onUpdate)

        .catch(onError);

      ;

    }

  }).catch(onError);

}

updateOrCreate(

  models.NewsItem, {title: 'sometitle1'}, {title: 'sometitle'},

  function () {

    console.log('created');

  },

  function () {

    console.log('updated');

  },

  console.log);

User.upsert({ a: 'a', b: 'b', username: 'john' })
it('works with upsert on id', function() {

  return this.User.upsert({ id: 42, username: 'john' }).then(created => {

    if (dialect === 'sqlite') {

      expect(created).to.be.undefined;

    } else {

      expect(created).to.be.ok;

    }



    this.clock.tick(1000);

    return this.User.upsert({ id: 42, username: 'doe' });

  }).then(created => {

    if (dialect === 'sqlite') {

      expect(created).to.be.undefined;

    } else {

      expect(created).not.to.be.ok;

    }



    return this.User.findByPk(42);

  }).then(user => {

    expect(user.createdAt).to.be.ok;

    expect(user.username).to.equal('doe');

    expect(user.updatedAt).to.be.afterTime(user.createdAt);

  });

});
new Sequelize.Utils.CustomEventEmitter(function(emitter) {

  if(data.id){

    Model.update(data, {id: data.id })

    .success(function(){

      emitter.emit('success', data.id );

    }).error(function(error){

      emitter.emit('error', error );

    });

  } else {

    Model.build(data).save().success(function(d){

      emitter.emit('success', d.id );

    }).error(function(error){

      emitter.emit('error', error );

    });

  }

}).success(function(data_id){

  // Your callback stuff here

}).error(function(error){

 // error stuff here

}).run(); // kick off the queriesvar Promise = require('promise');

var PushToken = require("../models").PushToken;



var createOrUpdatePushToken = function (deviceID, pushToken) {

 return new Promise(function (fulfill, reject) {

  PushToken

   .findOrCreate({

    where: {

     deviceID: deviceID

    }, defaults: {

     pushToken: pushToken

    }

   })

   .spread(function (foundOrCreatedPushToken, created) {

    if (created) {

     fulfill(foundOrCreatedPushToken);

    } else {

     foundOrCreatedPushToken

      .update({

       pushToken: pushToken

      })

      .then(function (updatedPushToken) {

       fulfill(updatedPushToken);

      })

      .catch(function (err) {

       reject(err);

      });

    }

   });

 });

};
async.auto({

 getInstance : function(cb) {

   Model.findOrCreate({

    attribute : value,

    ...

   }).complete(function(err, result) {

    if (err) {

     cb(null, false);

    } else {

     cb(null, result);

    }

   });

  },

  updateInstance : ['getInstance', function(cb, result) {

   if (!result || !result.getInstance) {

    cb(null, false);

   } else {

    result.getInstance.updateAttributes({

     attribute : value,

     ...

    }, ['attribute', ...]).complete(function(err, result) {

     if (err) {

      cb(null, false);

     } else {

      cb(null, result);

     }

    });

   }

   }]

  }, function(err, allResults) {

   if (err || !allResults || !allResults.updateInstance) {

    // job not done

   } else {

    // job done

  });

});

用法

function upsert(values, condition) {

  return Model

    .findOne({ where: condition })

    .then(function(obj) {

      // updateif(obj)

        return obj.update(values);

      // insert

      return Model.create(values);

    })

}
upsert({ first_name: 'Taku' }, { id: 1234 }).then(function(result){

  res.status(200).send({success: true});

});
async function updateOrCreate (model, where, newItem) {

  // First try to find the record

 const foundItem = await model.findOne({where});

 if (!foundItem) {

    // Item not found, create a new one

    const item = await model.create(newItem)

    return {item, created: true};

  }

  // Found an item, update it

  const item = await model.update(newItem, {where});

  return {item, created: false};

}

function updateOrCreate (model, where, newItem) {

  // First try to find the record

  return model

  .findOne({where: where})

  .then(function (foundItem) {

    if (!foundItem) {

      // Item not found, create a new one

      return model

        .create(newItem)

        .then(function (item) { return {item: item, created: true}; })

    }

    // Found an item, update it

    return model

      .update(newItem, {where: where})

      .then(function (item) { return {item: item, created: false} }) ;

  }

}
updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})

  .then(function(result) {

    result.item; // the model

    result.created; // bool, if a new item was created.

  });
updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})

  .then(..)

  .catch(function(err){});
var updateOrCreate = function (model, where, newItem, onCreate, onUpdate, onError) {

  // First try to find the record

  model.findOne({where: where}).then(function (foundItem) {

    if (!foundItem) {

      // Item not found, create a new one

      model.create(newItem)

        .then(onCreate)

        .catch(onError);

    } else {

      // Found an item, update it

      model.update(newItem, {where: where})

        .then(onUpdate)

        .catch(onError);

      ;

    }

  }).catch(onError);

}

updateOrCreate(

  models.NewsItem, {title: 'sometitle1'}, {title: 'sometitle'},

  function () {

    console.log('created');

  },

  function () {

    console.log('updated');

  },

  console.log);

User.upsert({ a: 'a', b: 'b', username: 'john' })
it('works with upsert on id', function() {

  return this.User.upsert({ id: 42, username: 'john' }).then(created => {

    if (dialect === 'sqlite') {

      expect(created).to.be.undefined;

    } else {

      expect(created).to.be.ok;

    }



    this.clock.tick(1000);

    return this.User.upsert({ id: 42, username: 'doe' });

  }).then(created => {

    if (dialect === 'sqlite') {

      expect(created).to.be.undefined;

    } else {

      expect(created).not.to.be.ok;

    }



    return this.User.findByPk(42);

  }).then(user => {

    expect(user.createdAt).to.be.ok;

    expect(user.username).to.equal('doe');

    expect(user.updatedAt).to.be.afterTime(user.createdAt);

  });

});
new Sequelize.Utils.CustomEventEmitter(function(emitter) {

  if(data.id){

    Model.update(data, {id: data.id })

    .success(function(){

      emitter.emit('success', data.id );

    }).error(function(error){

      emitter.emit('error', error );

    });

  } else {

    Model.build(data).save().success(function(d){

      emitter.emit('success', d.id );

    }).error(function(error){

      emitter.emit('error', error );

    });

  }

}).success(function(data_id){

  // Your callback stuff here

}).error(function(error){

 // error stuff here

}).run(); // kick off the queriesvar Promise = require('promise');

var PushToken = require("../models").PushToken;



var createOrUpdatePushToken = function (deviceID, pushToken) {

 return new Promise(function (fulfill, reject) {

  PushToken

   .findOrCreate({

    where: {

     deviceID: deviceID

    }, defaults: {

     pushToken: pushToken

    }

   })

   .spread(function (foundOrCreatedPushToken, created) {

    if (created) {

     fulfill(foundOrCreatedPushToken);

    } else {

     foundOrCreatedPushToken

      .update({

       pushToken: pushToken

      })

      .then(function (updatedPushToken) {

       fulfill(updatedPushToken);

      })

      .catch(function (err) {

       reject(err);

      });

    }

   });

 });

};
async.auto({

 getInstance : function(cb) {

   Model.findOrCreate({

    attribute : value,

    ...

   }).complete(function(err, result) {

    if (err) {

     cb(null, false);

    } else {

     cb(null, result);

    }

   });

  },

  updateInstance : ['getInstance', function(cb, result) {

   if (!result || !result.getInstance) {

    cb(null, false);

   } else {

    result.getInstance.updateAttributes({

     attribute : value,

     ...

    }, ['attribute', ...]).complete(function(err, result) {

     if (err) {

      cb(null, false);

     } else {

      cb(null, result);

     }

    });

   }

   }]

  }, function(err, allResults) {

   if (err || !allResults || !allResults.updateInstance) {

    // job not done

   } else {

    // job done

  });

});

注意

  • 这个操作不是原子的。
  • 创建 2 个网络调用。
  • 这意味着建议重新考虑该方法,并且可能只更新一次网络调用中的值,并且:

  • 查看返回的值(即 rows_affected)并决定要做什么。
  • 如果更新操作成功则返回成功。这是因为资源是否存在不在本服务的职责范围内。

  • 你可以使用 upsert

    这更容易。

    Implementation details:

    • MySQL - Implemented as a single query INSERT values ON DUPLICATE KEY UPDATE values
    • PostgreSQL - Implemented as a temporary function with exception handling: INSERT EXCEPTION WHEN unique_constraint UPDATE
    • SQLite - Implemented as two queries INSERT; UPDATE. This means that the update is executed regardless of whether the row already

      existed or not

    • MSSQL - Implemented as a single query using MERGE and WHEN (NOT) MATCHED THEN Note that SQLite returns undefined for created, no

      matter if the row was created or updated. This is because SQLite

      always runs INSERT OR IGNORE + UPDATE, in a single query, so there

      is no way to know whether the row was inserted or not.


    现在使用 async/await 更新 07/2019

    function upsert(values, condition) {
    
      return Model
    
        .findOne({ where: condition })
    
        .then(function(obj) {
    
          // updateif(obj)
    
            return obj.update(values);
    
          // insert
    
          return Model.create(values);
    
        })
    
    }
    upsert({ first_name: 'Taku' }, { id: 1234 }).then(function(result){
    
      res.status(200).send({success: true});
    
    });
    async function updateOrCreate (model, where, newItem) {
    
      // First try to find the record
    
     const foundItem = await model.findOne({where});
    
     if (!foundItem) {
    
        // Item not found, create a new one
    
        const item = await model.create(newItem)
    
        return {item, created: true};
    
      }
    
      // Found an item, update it
    
      const item = await model.update(newItem, {where});
    
      return {item, created: false};
    
    }
    
    function updateOrCreate (model, where, newItem) {
    
      // First try to find the record
    
      return model
    
      .findOne({where: where})
    
      .then(function (foundItem) {
    
        if (!foundItem) {
    
          // Item not found, create a new one
    
          return model
    
            .create(newItem)
    
            .then(function (item) { return {item: item, created: true}; })
    
        }
    
        // Found an item, update it
    
        return model
    
          .update(newItem, {where: where})
    
          .then(function (item) { return {item: item, created: false} }) ;
    
      }
    
    }
    updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})
    
      .then(function(result) {
    
        result.item; // the model
    
        result.created; // bool, if a new item was created.
    
      });
    updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})
    
      .then(..)
    
      .catch(function(err){});
    var updateOrCreate = function (model, where, newItem, onCreate, onUpdate, onError) {
    
      // First try to find the record
    
      model.findOne({where: where}).then(function (foundItem) {
    
        if (!foundItem) {
    
          // Item not found, create a new one
    
          model.create(newItem)
    
            .then(onCreate)
    
            .catch(onError);
    
        } else {
    
          // Found an item, update it
    
          model.update(newItem, {where: where})
    
            .then(onUpdate)
    
            .catch(onError);
    
          ;
    
        }
    
      }).catch(onError);
    
    }
    
    updateOrCreate(
    
      models.NewsItem, {title: 'sometitle1'}, {title: 'sometitle'},
    
      function () {
    
        console.log('created');
    
      },
    
      function () {
    
        console.log('updated');
    
      },
    
      console.log);
    
    User.upsert({ a: 'a', b: 'b', username: 'john' })
    it('works with upsert on id', function() {
    
      return this.User.upsert({ id: 42, username: 'john' }).then(created => {
    
        if (dialect === 'sqlite') {
    
          expect(created).to.be.undefined;
    
        } else {
    
          expect(created).to.be.ok;
    
        }
    
    
    
        this.clock.tick(1000);
    
        return this.User.upsert({ id: 42, username: 'doe' });
    
      }).then(created => {
    
        if (dialect === 'sqlite') {
    
          expect(created).to.be.undefined;
    
        } else {
    
          expect(created).not.to.be.ok;
    
        }
    
    
    
        return this.User.findByPk(42);
    
      }).then(user => {
    
        expect(user.createdAt).to.be.ok;
    
        expect(user.username).to.equal('doe');
    
        expect(user.updatedAt).to.be.afterTime(user.createdAt);
    
      });
    
    });
    new Sequelize.Utils.CustomEventEmitter(function(emitter) {
    
      if(data.id){
    
        Model.update(data, {id: data.id })
    
        .success(function(){
    
          emitter.emit('success', data.id );
    
        }).error(function(error){
    
          emitter.emit('error', error );
    
        });
    
      } else {
    
        Model.build(data).save().success(function(d){
    
          emitter.emit('success', d.id );
    
        }).error(function(error){
    
          emitter.emit('error', error );
    
        });
    
      }
    
    }).success(function(data_id){
    
      // Your callback stuff here
    
    }).error(function(error){
    
     // error stuff here
    
    }).run(); // kick off the queriesvar Promise = require('promise');
    
    var PushToken = require("../models").PushToken;
    
    
    
    var createOrUpdatePushToken = function (deviceID, pushToken) {
    
     return new Promise(function (fulfill, reject) {
    
      PushToken
    
       .findOrCreate({
    
        where: {
    
         deviceID: deviceID
    
        }, defaults: {
    
         pushToken: pushToken
    
        }
    
       })
    
       .spread(function (foundOrCreatedPushToken, created) {
    
        if (created) {
    
         fulfill(foundOrCreatedPushToken);
    
        } else {
    
         foundOrCreatedPushToken
    
          .update({
    
           pushToken: pushToken
    
          })
    
          .then(function (updatedPushToken) {
    
           fulfill(updatedPushToken);
    
          })
    
          .catch(function (err) {
    
           reject(err);
    
          });
    
        }
    
       });
    
     });
    
    };
    async.auto({
    
     getInstance : function(cb) {
    
       Model.findOrCreate({
    
        attribute : value,
    
        ...
    
       }).complete(function(err, result) {
    
        if (err) {
    
         cb(null, false);
    
        } else {
    
         cb(null, result);
    
        }
    
       });
    
      },
    
      updateInstance : ['getInstance', function(cb, result) {
    
       if (!result || !result.getInstance) {
    
        cb(null, false);
    
       } else {
    
        result.getInstance.updateAttributes({
    
         attribute : value,
    
         ...
    
        }, ['attribute', ...]).complete(function(err, result) {
    
         if (err) {
    
          cb(null, false);
    
         } else {
    
          cb(null, result);
    
         }
    
        });
    
       }
    
       }]
    
      }, function(err, allResults) {
    
       if (err || !allResults || !allResults.updateInstance) {
    
        // job not done
    
       } else {
    
        // job done
    
      });
    
    });

    我喜欢 Ataik 的想法,但把它缩短了一点:

    function upsert(values, condition) {
    
      return Model
    
        .findOne({ where: condition })
    
        .then(function(obj) {
    
          // updateif(obj)
    
            return obj.update(values);
    
          // insert
    
          return Model.create(values);
    
        })
    
    }
    upsert({ first_name: 'Taku' }, { id: 1234 }).then(function(result){
    
      res.status(200).send({success: true});
    
    });
    async function updateOrCreate (model, where, newItem) {
    
      // First try to find the record
    
     const foundItem = await model.findOne({where});
    
     if (!foundItem) {
    
        // Item not found, create a new one
    
        const item = await model.create(newItem)
    
        return {item, created: true};
    
      }
    
      // Found an item, update it
    
      const item = await model.update(newItem, {where});
    
      return {item, created: false};
    
    }
    
    function updateOrCreate (model, where, newItem) {
    
      // First try to find the record
    
      return model
    
      .findOne({where: where})
    
      .then(function (foundItem) {
    
        if (!foundItem) {
    
          // Item not found, create a new one
    
          return model
    
            .create(newItem)
    
            .then(function (item) { return {item: item, created: true}; })
    
        }
    
        // Found an item, update it
    
        return model
    
          .update(newItem, {where: where})
    
          .then(function (item) { return {item: item, created: false} }) ;
    
      }
    
    }
    updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})
    
      .then(function(result) {
    
        result.item; // the model
    
        result.created; // bool, if a new item was created.
    
      });
    updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})
    
      .then(..)
    
      .catch(function(err){});
    var updateOrCreate = function (model, where, newItem, onCreate, onUpdate, onError) {
    
      // First try to find the record
    
      model.findOne({where: where}).then(function (foundItem) {
    
        if (!foundItem) {
    
          // Item not found, create a new one
    
          model.create(newItem)
    
            .then(onCreate)
    
            .catch(onError);
    
        } else {
    
          // Found an item, update it
    
          model.update(newItem, {where: where})
    
            .
    (0)
    « 上一篇
    下一篇 »

相关推荐

  • Spring部署设置openshift

    Springdeploymentsettingsopenshift我有一个问题让我抓狂了三天。我根据OpenShift帐户上的教程部署了spring-eap6-quickstart代码。我已配置调试选项,并且已将Eclipse工作区与OpehShift服务器同步-服务器上的一切工作正常,但在Eclipse中出现无法消除的错误。我有这个错误:cvc-complex-type.2.4.a:Invali…
    2025-04-161
  • 检查Java中正则表达式中模式的第n次出现

    CheckfornthoccurrenceofpatterninregularexpressioninJava本问题已经有最佳答案,请猛点这里访问。我想使用Java正则表达式检查输入字符串中特定模式的第n次出现。你能建议怎么做吗?这应该可以工作:MatchResultfindNthOccurance(intn,Patternp,CharSequencesrc){Matcherm=p.matcher…
    2025-04-161
  • 如何让 JTable 停留在已编辑的单元格上

    HowtohaveJTablestayingontheeditedcell如果有人编辑JTable的单元格内容并按Enter,则内容会被修改并且表格选择会移动到下一行。是否可以禁止JTable在单元格编辑后转到下一行?原因是我的程序使用ListSelectionListener在单元格选择上同步了其他一些小部件,并且我不想在编辑当前单元格后选择下一行。Enter的默认绑定是名为selectNext…
    2025-04-161
  • Weblogic 12c 部署

    Weblogic12cdeploy我正在尝试将我的应用程序从Tomcat迁移到Weblogic12.2.1.3.0。我能够毫无错误地部署应用程序,但我遇到了与持久性提供程序相关的运行时错误。这是堆栈跟踪:javax.validation.ValidationException:CalltoTraversableResolver.isReachable()threwanexceptionatorg.…
    2025-04-161
  • Resteasy Content-Type 默认值

    ResteasyContent-Typedefaults我正在使用Resteasy编写一个可以返回JSON和XML的应用程序,但可以选择默认为XML。这是我的方法:@GET@Path("/content")@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})publicStringcontentListRequestXm…
    2025-04-161
  • 代码不会停止运行,在 Java 中

    thecodedoesn'tstoprunning,inJava我正在用Java解决项目Euler中的问题10,即"Thesumoftheprimesbelow10is2+3+5+7=17.Findthesumofalltheprimesbelowtwomillion."我的代码是packageprojecteuler_1;importjava.math.BigInteger;importjava…
    2025-04-161
  • Out of memory java heap space

    Outofmemoryjavaheapspace我正在尝试将大量文件从服务器发送到多个客户端。当我尝试发送大小为700mb的文件时,它显示了"OutOfMemoryjavaheapspace"错误。我正在使用Netbeans7.1.2版本。我还在属性中尝试了VMoption。但仍然发生同样的错误。我认为阅读整个文件存在一些问题。下面的代码最多可用于300mb。请给我一些建议。提前致谢publicc…
    2025-04-161
  • Log4j 记录到共享日志文件

    Log4jLoggingtoaSharedLogFile有没有办法将log4j日志记录事件写入也被其他应用程序写入的日志文件。其他应用程序可以是非Java应用程序。有什么缺点?锁定问题?格式化?Log4j有一个SocketAppender,它将向服务发送事件,您可以自己实现或使用与Log4j捆绑的简单实现。它还支持syslogd和Windows事件日志,这对于尝试将日志输出与来自非Java应用程序…
    2025-04-161