Вставки/транзакции Pg-promise не работают в асинхронной очереди

Я нашел много вещей, связанных с использованием pg-promise и await/async, но ничего, что полностью отвечало бы моей проблеме с async (пакет node/npm) и, в частности, взаимодействие между запросами async.queue и pg-promise.

Моя проблема: мне нужно выполнить несколько миллионов вычислений (сопоставление баллов) асинхронно и зафиксировать их результаты в том же асинхронном процессе в базе данных postgres. Мой основной процесс — это промис, который сначала вычисляет все возможные различные комбинации двух записей из таблицы и сегментирует их на куски по тысяче пар за раз.

Эти фрагменты из тысячи пар (т. е. [[0,1], [0,2], ..., [0, 1000]] — это мой массив содержимого первого индекса фрагментов) передаются экземпляру async. очередь, которая сначала выполняет вычисление оценки совпадения, а затем запись в БД.

Часть, которая заставила меня почесать голову в течение нескольких часов, заключается в том, что фиксация базы данных не работает, независимо от того, используются ли операторы вставки или транзакции. Я точно знаю, что функции, которые я использую для части 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, как и ожидалось,
  • если я проверяю любой из массивов (chunk, chunksArray, scores и т.д.) все в порядке, длины правильные, их содержимое тоже.

pg-promise просто не хочет помещать мои 1000 записей за раз в базу данных при использовании с async.queue, и именно здесь я застрял. Мне нетрудно представить, что вина лежит на мне, я впервые использую async.queue, особенно в сочетании с обещаниями bluebird и pg-promise.

Заранее большое спасибо за то, что нашли время прочитать это и пролить свет на этот вопрос, если сможете.


person SpicySquidInk    schedule 12.06.2018    source источник
comment
Вы читали github.com/vitaly-t/ пг-обещание/вики/ ?   -  person Jonke    schedule 15.06.2018


Ответы (2)


У меня была такая же проблема на одной из моих машин, но ни на одной другой. Мне помогло обновление pg-promise с версии 10.5.0 до версии 10.5.6 (через npm update pg-promise).

person Vivek Bari    schedule 24.12.2020

Ваш mainPromise не ждет завершения выполнения DBCommitting:

должно быть так:

//commit those scores to the db using pg-promise
performDbCommitting(db, scores).then(()=>{done();});

и PerformDBCommitting также должен вернуть обещание:

return db.any(query).then(data => {
    console.log('test2');
    //nothing is displayed
    console.log(data);
    //nothing is displayed
    return null;
}).catch(err => {
    console.error(err);
    return null;
});
person bknights    schedule 12.06.2018
comment
Привет! Спасибо за ваш отзыв, вы правы, моя основная очередь/обещание не ожидала вставки pg-promise, хотя даже с предложенными вами изменениями вставки в базу данных не происходят. - person SpicySquidInk; 13.06.2018
comment
Я обнаружил, используя меньший набор тестов (два фрагмента по 1000 записей для вычисления), что по какой-то причине pg-promise ждет, пока aync.queue не обработает все оценки, чтобы начать писать и решать свои собственные промисы, совершенно сбитый с толку этим. - person SpicySquidInk; 13.06.2018