Как пройти через многострочный SQL-запрос и использовать их в Knex Transactions?

62
7

Новичок в 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()? Каковы их различия?

Заранее спасибо!

спросил(а) 2021-01-19T14:40:36+03:00 2 месяца, 3 недели назад
1
Решение
76

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

ответил(а) 2021-01-19T14:40:36+03:00 2 месяца, 3 недели назад
62

Как-то так это нахальный способ сделать это:

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

При работе с транзакциями обычно требуется создавать и запускать запросы один за другим, чтобы избежать ненужной буферизации запросов перед выполнением их через соединение с одной БД транзакции.

ответил(а) 2021-01-19T14:40:36+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема