Knex.js Knexjs如果不存在,则插入else更新

Knex.js Knexjs如果不存在,则插入else更新,knex.js,Knex.js,如何优化此代码? 我不想给那里打两次电话。。。有可能有比这更好的查询吗 return self.db.clientDevices.where(device).then(function (rows) { if (rows.length != 1) { device.key = value; self.db.clientDevices.insert(device).then(); } else {

如何优化此代码? 我不想给那里打两次电话。。。有可能有比这更好的查询吗

    return self.db.clientDevices.where(device).then(function (rows) {
        if (rows.length != 1) {
            device.key = value;
            self.db.clientDevices.insert(device).then();
        } else {
            self.db.clientDevices.where(device).update(device).then();
        }
    });

请尝试使用原始sql对重复密钥更新执行
,因为knex目前不支持此操作


请参阅:

假设您有一个唯一的键(本例中为post_id)和一个对象数组(blogPosts),则可以使用以下帮助器方法:

函数insertOrUpdate(表名、博客帖子){
返回knex.transaction(trx=>{
let querys=blogPosts.map(元组=>
trx.raw(util.format(“%s ON CONFLICT(post_id))不更新集%s',
trx(tableName).insert(tuple).toString().toString(),
trx(tableName).update(tuple).whereRaw(`${tableName}.post\u id='${tuple.post\u id}`).toString().replace(/^update\s.\sset\s/i'))
))               
.交易(trx)
);
返回Promise.all(查询).then(trx.commit).catch(trx.rollback);
})
}
并以此方式援引:

insertOrUpdate('posts',[
{post_id:1,内容:'Blog post 1'},
{post_id:2,内容:'Blog post 2'}
]);

刚刚修复了@sebydd regex,删除格式并将逻辑从“冲突时”更改为“重复密钥更新时”:


如果您使用的是
PostgreSQL
,因为在重复密钥更新中没有
。因此,在
PostgreSQL
中,您应该对冲突(“id”)DO UPDATE SET使用

const insertOrUpdate = (knex, tableName, data) => {
  const firstData = data[0] ? data[0] : data;

  return knex().raw(
    knex(tableName).insert(data).toQuery() + ' ON CONFLICT ("id") DO UPDATE SET ' +
      Object.keys(firstData).map((field) => `${field}=EXCLUDED.${field}`).join(', ')
  );
};
如果您使用的是
objective.js
(knex的包装器),那么(在这种情况下不要忘记导入knex):


不确定它是何时添加的,by knex现在有一个
onConflict
方法:。我以这种方式编写了一个“upsert”函数,它似乎可以与mysql配合使用:

module.exports = (table, idKey, data) => require('../knex')(table)
  .insert(data)
  .onConflict(idKey)
  .merge()
  .catch( err => {
    console.error(`There was an error upserting the "${table}" table by ${idKey}:`, err)
    throw err
  })
const insertOrUpdate = (model, tableName, data) => {
  const firstData = data[0] ? data[0] : data;

  return model.knex().raw(
    knex(tableName).insert(data).toQuery() + ' ON CONFLICT ("id") DO UPDATE SET ' +
      Object.keys(firstData).map((field) => `${field}=EXCLUDED.${field}`).join(', ')
  );
};
module.exports = (table, idKey, data) => require('../knex')(table)
  .insert(data)
  .onConflict(idKey)
  .merge()
  .catch( err => {
    console.error(`There was an error upserting the "${table}" table by ${idKey}:`, err)
    throw err
  })