pg-promise - невозможно получить ответ БД при использовании пакета

Я пытаюсь получить ответ из базы данных, когда использую tx.batch.

Спасибо.

  • 1) запросите базу данных для уже существующих записей, которые необходимо обновить
  • 2) используя результаты из 1, сделайте еще один пакетный вызов БД для создания или обновления записей
  • 3) ответить со статусом 200 на мой API с созданными и обновленными записями

Пакетные вызовы работают, проверенные записи вставляются и/или обновляются в БД.

 db.tx(t1 => {
    let queryCheck = [];

    reqData.forEach(obj => {
      for (let key in obj) {
        obj[key].resovledURLs.forEach(data => {
          queryCheck.push(
            t1.any(
              `SELECT * FROM testDB WHERE url='${key}' AND testurl='${data}';`
            )
          );
        });
      }
    });

    return t1
      .batch(queryCheck)
      .then(data => {

        return t1.tx(t2 => {
          let t2QueryBatch = [];

         // got rid of queryBatchOfEverything()
         // uses data from t1.batch(queryCheck) to make joinedArray
         let joinedArray = updateArray.concat(createArray);

          joinedArray.forEach(obj => {
            if (obj.queryType === "Update") {
              t2QueryBatch.push(
                t2.none(
                  `UPDATE testDB SET count = count + 1 WHERE url='${
                    obj.url
                  }' AND errorurl='${obj.testurl}';`
                )
              );
            } else {
              t2QueryBatch.push(
                t2.none(
                  `INSERT INTO testDB (url, testurl) VALUES ('${
                    obj.url
                  }', '${obj.testurl}');`
                )
              );
            }
          });

          return t2.batch(t2QueryBatch);
        });
      })
      .then(data => {
        console.log(data);
      });
  });

person David Trinh    schedule 06.08.2018    source источник


Ответы (1)


В вашем коде так много проблем, что невозможно дать совет по точной проблеме. Вам нужно будет тщательно пересмотреть код, прежде чем станет возможной какая-либо дальнейшая диагностика.

Сразу заметны проблемы в вашем коде...

проблема 1

Вы забыли связать queryBatchOfEverything с транзакцией, которая его содержит, то есть это должно быть return queryBatchOfEverything..., если это ваша транзакционная логика.

проблема 2

Вы открываете вложенную транзакцию в объекте db, что является недопустимым, т. е. вы не можете создать независимую транзакцию верхнего уровня, находясь внутри другой транзакции.

Вы можете создать там только подтранзакцию, она же savepoint, из контекста родительской транзакции, т.е. t1.tx(t2 => {}).

проблема 3

Вы забыли связать результат вложенной транзакции с родительской транзакцией, так что еще одно неопределенное обещание в ваших руках. Это должно быть return t1.tx(t2 => )

проблема 4

Вы используете метод one внутри вложенной транзакции, что означает, что вы ожидаете ровно одну строку данных обратно, в то время как ни один из ваших запросов ничего не возвращает, т.е. вместо этого вы должны использовать метод none. Это та самая проблема, о которой вы спрашивали. Но вам нужно исправить остальное, чтобы все работало правильно.

проблема 5

Вы не привязываете t2.batch к транзакции, создавая еще одно расплывчатое обещание. Должно быть return t2.batch.

проблема 6

Это не проблема, просто какой-то бесполезный код:

let updateRecords = await t1.batch(queryCheck).then(data => {
    return data;
});

Это точно так же, как это:

let updateRecords = await t1.batch(queryCheck);
person vitaly-t    schedule 06.08.2018
comment
Спасибо за указание на мои ошибки, я думаю, что внес все изменения, о которых вы упомянули, поэтому я больше не получаю сообщение об ошибке, но теперь я получаю: [ null, null, null ]. Где я ошибся? - person David Trinh; 07.08.2018
comment
@DavidTrinh Если вы вернете batch[none, none, none], оно будет преобразовано в [null, null, null], как и ожидалось, поскольку none в случае успеха разрешается в null. - person vitaly-t; 07.08.2018