Node.js 如何循环执行多行sql查询并在Knex事务中使用它们?

Node.js 如何循环执行多行sql查询并在Knex事务中使用它们?,node.js,knex.js,Node.js,Knex.js,Node和Knex中的新手来自RoR背景,我需要将特定函数转换为Node.js 这是我的RoR代码: def self.save! update_queries = self.fetch.map{|currency, rate| "UPDATE currency_exchange_rates SET rate='#{rate}' WHERE currency='#{currency}'" }.join(';') ActiveRecord::Base.co

Node和Knex中的新手来自RoR背景,我需要将特定函数转换为Node.js

这是我的RoR代码:

  def self.save!
    update_queries = self.fetch.map{|currency, rate|
      "UPDATE currency_exchange_rates SET rate='#{rate}' WHERE currency='#{currency}'"
    }.join(';')

    ActiveRecord::Base.connection.execute(update_queries)
  end
到目前为止,我在Nodejs中有以下内容:

static save(new_rates){
      return new Promise(async (resolve, reject) => {
        var query = Object.keys(rate).map(key => 'UPDATE currency_exchange_rates SET rate=' + rate[key] + ' WHERE currency = "' + key + '"').join('; ');
    })
  }
以下是输入数据的外观:

新利率=

'UPDATE currency_exchange_rates SET rate=32102793.12 WHERE currency= "IDR"; 

UPDATE currency_exchange_rates SET rate=0.7822 WHERE currency= "USDGBP"; 

UPDATE currency_exchange_rates SET rate=3189.756317 WHERE currency= "CAD"; 

UPDATE currency_exchange_rates SET rate=152.8 WHERE currency= "USDLKR"; 

UPDATE currency_exchange_rates SET rate=110.818 WHERE currency= "USDJPY"; 

UPDATE currency_exchange_rates SET rate=1.3103 WHERE currency= "USDAUD"'
我正在使用
Knex.js
连接到我的pg数据库。如何使用knex执行所有这些操作?我可以在
knex.raw()
中传递所有查询吗?怎么样
knex.transaction()
?他们的区别是什么


提前谢谢

类似这样的做法是Kneyx的做法:

let retVal = await knex.transaction(async (trx) => {
  for (let key of Object.keys(rate)) {
    let value = rate[key];
    await trx('currency_exchange_rates')
      .update({ rate: value }).where('currency', key);
  }
  return "woo done"; // this value is returned from transaction 
});

在处理交易时,通常,在通过事务的单个DB连接运行查询之前,您希望逐个创建和运行查询,以避免不必要的查询缓冲。

您可以使用
bluebird
mapSeries
哦,谢谢我会检查,谢谢您提供关于为什么要逐个运行查询的脚注。我一直在试着理解,还有交易!我不太明白为什么。交易仍然需要时。更新可以做的工作已经?谢谢@请查看任何SQL教程或维基百科等。事务的含义以及使用它们的原因。基本上,它允许将所有更新作为一个原子操作进行,其中要么将所有更新提交给数据库,要么即使其中一个失败,所有更新都将被拒绝。如果有大量数据需要更新,这种为每个查询并行创建查询生成器的方式将以非常低效的方式使用内存。所有查询生成器都是并行创建的,所有查询都发送到驱动程序并行,然后驱动程序只是缓冲所有查询,并且仍然会通过事务的单个连接按顺序运行这些查询。虽然通常只更新少量数据并不重要。@MikaelLepistö感谢您的输入,他正在阅读您两个答案之间的差异。为了简单起见,我确实使用了你的答案,但这个回答更好地解释了它的区别。再次感谢!
// [Sequential Update] Commit transaction after each successfully executed query
await knex.transaction(async trx => {
    return Promise.all(Object.keys(rate).map(key => trx('currency_exchange_rates')
            .update({ rate: rate[key] })
            .where({ currency: key })
    ));
});

// [Bulk Update] Commit transaction after all queries have been executed successfully
await knex.transaction(trx => {
    return Promise.all(Object.keys(rate).map(key => knex('currency_exchange_rates')
            .update({ rate: rate[key] })
            .where({ currency: key })
        ))
        .then(trx.commit)
        .catch(trx.rollback);
});