【发布时间】:2020-05-15 11:56:43
【问题描述】:
我在 Node 中运行 knex seed,由于服务器的限制,我需要对我的数据库进行批量查询。我开始掌握 Promise 和 async/await 的窍门,但是我很难让它在几个层次上工作(在这一点上让我特别失望的是,它似乎干扰了批处理我无法理解的方式)。我的seed 文件如下所示:
exports.seed = async function(knex) {
const fs = require('fs');
const _ = require('lodash');
function get_event_id(location) {
return knex('events')
.where({location: location})
.first()
.then(result => { return result['id']; })
.finally(() => { knex.destroy() })
}
function createImage(row, event_id) {
return {
name: row[4],
event_id: event_id
}
};
async function run_query(line) {
let row = line.split(',');
let event_id = await get_event_id(row[0]);
return createImage(row, event_id);
};
async function run_batch(batch) {
return Promise.all(batch.map(run_query));
}
const file = fs.readFileSync('./data.csv');
const lines = file.toString().replace(/[\r]/g, '').split('\n').slice(1,60); // skip csv header, then run first 59 lines
const batches = _.chunk(lines, 30); // set batch size
let images = await Promise.all(batches.map(run_batch));
console.log(_.flatten(images).length);
};
我的数据库一次可以处理 30 个查询。如果我在定义lines 的行上使用.slice(1,30) 运行单个批处理,一切都会正确解决。但是如上所述以 60 运行给了我ER_TOO_MANY_USER_CONNECTIONS: User already has more than 'max_user_connections' active connections。
如果我将run_batch 的内容更改为return batch.map(run_query),脚本就会完成,并且它会返回正确的条目数(因此它似乎正在正确地进行批处理)。但是,Promises 仍然悬而未决。我错过了什么,有没有更优雅的方法来做到这一点?
【问题讨论】:
标签: javascript node.js asynchronous promise knex.js