javascript - Pg-promise 插入/事务在异步队列中不起作用
问题描述
我发现了很多与使用 pg-promise 和 await/async 相关的东西,但没有什么能完全回答我的异步问题(node/npm 包),特别是 async.queue 和 pg-promise 查询之间的交互。
我的问题:我需要异步进行几百万次计算(匹配分数),并将它们的结果提交到 postgres 数据库中的同一个异步进程中。我的主要过程是一个承诺,它首先计算表中两条记录的所有可能的不同组合,并一次将它们分成一千对的块。
这些一千对的块(即 [[0,1], [0,2], ... , [0, 1000]] 是我的块的第一个索引内容数组)被馈送到异步实例。首先执行匹配分数计算然后执行数据库记录的队列。
让我挠头好几个小时的部分是,无论是使用插入语句还是事务,数据库提交都不起作用。我确信我用于 db 部分的函数可以工作,因为我已经使用它们编写了手动测试。
我的主要代码如下:
'use strict';
const promise = require('bluebird');
const initOptions = {
promiseLib: promise
};
const pgp = require('pg-promise')(initOptions);
const cn = {connexion parameters...};
const db = pgp(cn);
const async = require('async');
var mainPromise = (db, php, param) => {
return new Promise(resolve => {
//some code computing the chunksArray using param
...
var q = async.queue((chunk, done) => {
var scores = performScoresCalculations(chunk);
//scores is an array containing the 1000 scores for any chunk of a 1000 pairs
performDbCommitting(db, scores);
//commit those scores to the db using pg-promise
done();
}, 10);
q.drain = () => {
resolve(arr);
//admittedly not quite sure about that part, haven't used async.queue much so far
}
q.push(chunksArray);
)}.catch(err => {
console.error(err);
});
};
现在我的分数数组如下所示:
[{column1:'value1_0',column2:'value2_0',...,columnN:'valueN_0'},...,{column1:'value1_999',column2:'value2_999',column3:'value3_999'}]一千条记录在里面。
我的 performDbCommitting 函数如下:
var performDbCommitting = (db, pgp, scores) => {
console.log('test1');
//displays 'test1', as expected
var query = pgp.helpers.insert(scores, ['column1', 'column2', 'column3'], 'myScoreTable');
console.log(query);
//display the full content of the query, as expected
db.any(query).then(data => {
console.log('test2');
//nothing is displayed
console.log(data);
//nothing is displayed
return;
}).catch(err => {
console.error(err);
});
}
所以这是我的问题:
- 当“手动”测试 performDbCommitting 工作完美时,我什至尝试了一个带有事务的版本,同样工作完美,
- 当在 async.queue 中使用时, performDbCommitting 中的所有内容似乎都可以工作,直到 db.any(query) 调用为止,console.log 正确显示信息就证明了这一点,
- 没有抛出错误,对 chunksArray 的计算按预期按 1000 组继续进行,
- 如果我检查任何数组(块、块数组、分数等),一切都应该是正确的,长度是正确的,它们的内容也是正确的。
当与 async.queue 一起使用时,pg-promise 似乎不想一次将我的 1000 条记录推送到数据库中,这就是我遇到的问题。我可以毫不费力地想象问题出在我身上,这大约是我第一次使用 async.queue,尤其是与 bluebird promise 和 pg-promise 混合使用。
非常感谢您抽出宝贵时间阅读本文并在可能的情况下阐明此问题。
解决方案
我特别是在我的一台机器上遇到了同样的问题,但在其他机器上都没有。对我有用的是将 pg-promise 从 10.5.0 版更新到 10.5.6 版(通过 npm update pg-promise)。