nodejs, postgres и bluebird

Я пытался использовать обещания bluebird с библиотекой pg и даже нашел этот пост, но, к сожалению, я слишком новичок в использовании StackOverflow, чтобы просто комментировать его напрямую: Ручное обещание pg.connect с помощью Bluebird

Проще говоря, все, что я пробовал с функцией bluebird Promisfy после вырезания и вставки этого кода, не использует ни один из конструкторов запросов, и, возможно, я неправильно использую функцию ClientAsync в своих попытках, но я надеюсь, что это быстрая и простая помощь, так как все, что я пробую, приводит к некоторому варианту:

Possibly unhandled TypeError: Object function (err) {
      if(err) {
        pool.destroy(client);
      } else {
        pool.release(client);
      }
    } has no method 'queryAsync'

Я сбросил результат функции PromisfyAll, и, конечно же, queryAsync отсутствует:

Соответствующий фрагмент:

Client: { [Function] Query: { [Function] super_: [Object] } },
Query:
  { [Function]
    super_: { [Function: EventEmitter] listenerCount: [Function] } },
pools:
  { all: {},
    Client: { [Function] Query: [Object] },
    getOrCreate: [Function] },
Connection:
 { [Function]
   super_: { [Function: EventEmitter] listenerCount: [Function] } },
types:
 { getTypeParser: [Function],
   setTypeParser: [Function],
   arrayParser: { create: [Function] } },
ClientAsync: { [Function: ClientAsync] __isPromisified__: true },
endAsync: { [Function: endAsync] __isPromisified__: true },
connectAsync: { [Function: connectAsync] __isPromisified__: true },
cancelAsync: { [Function: cancelAsync] __isPromisified__: true },
setMaxListenersAsync: { [Function: setMaxListenersAsync] __isPromisified__: true },
emitAsync: { [Function: emitAsync] __isPromisified__: true },
addListenerAsync: { [Function: addListenerAsync] __isPromisified__: true },
onAsync: { [Function: onAsync] __isPromisified__: true },
onceAsync: { [Function: onceAsync] __isPromisified__: true },
removeListenerAsync: { [Function: removeListenerAsync] __isPromisified__: true },
removeAllListenersAsync: { [Function: removeAllListenersAsync] __isPromisified__: true },
listenersAsync: { [Function: listenersAsync] __isPromisified__: true } }

Он находит соответствующие функции в синтаксическом анализе, но не обещает Query: кто-нибудь знает, как я могу устранить эту проблему или потенциальный синтаксис для выполнения SQL-запроса с ClientAsync? Я попытался добавить файл pg query.js вручную из информации на странице github Bluebird, но безрезультатно.


person Geoff    schedule 30.06.2014    source источник


Ответы (3)


Что ж, оказывается, это разница в Javascript и собственной библиотеке привязок при использовании Promisfy.

var pg = require('pg');
var Promise = require('bluebird');

var db = Promise.promisifyAll(pg);

var connectionString = "postgres://node:node@localhost:5432/postgres";

db.connectAsync("postgres://node:node@localhost:5432/postgres").spread(function(connection, release) {
  return connection.queryAsync("select * from howdy")
     .then(function(result) {
        console.log("rows", result.rows);
     })
     .finally(function() {
        release();
     });
});

Работает, тогда как это:

var pg = require('pg').native;
var Promise = require('bluebird');

Перерывы с уродливым сообщением об ошибке.

Я предполагаю, что в конечном итоге мне нужно будет провести некоторое сравнение между различными вариантами (bluebird w/promisfy и JS-bindings против C-bindings (libpq) и ручными обещаниями.

person Geoff    schedule 02.07.2014

Если вы хотите получить максимальную отдачу от архитектуры Promises/A+, присоединившись к библиотека PG и Bluebird вместе попробуйте pg-promise.

Ручное промисирование не даст почти никаких преимуществ, которые обещания могли бы предложить базе данных при правильном использовании, например, управление соединениями, автоматические транзакции и т. д.

Просто чтобы дать вам представление, вот как выглядит полная транзакция с pg-promise, красиво скрытие сведений о соединении и транзакции:

db.tx(function () {
    return this.batch([
        this.query("update users set active=$1 where id=$2", [true, 123]),
        this.query("insert into audit(status, id) values($1, $2)", ['active', 123])
    ]);
})
    .then(function (data) {
        // success;
    }, function (reason) {
        // error;
    });

И та же самая логика через обещанную вручную версию была бы в разы дольше, и намного сложнее. На самом деле, вам все равно придется сделать все следующее:

  • Открытое соединение;
  • Проверить соединение на успешность;
  • Выполнить команду BEGIN;
  • Выполнять последовательность ваших запросов;
  • Проверьте, были ли ваши запросы успешными;
  • Выполните либо COMMIT, либо ROLLBACK, в зависимости от успешности ваших запросов;
  • Убедитесь, что транзакция была успешно закрыта;
  • Отпустить соединение обратно в пул;
  • Вернуть результат для дальнейшей обработки;

теперь рассмотрим вложенные транзакции :)

person vitaly-t    schedule 14.04.2015

Создатель bluebird ответил на связанный вопрос здесь Ручное обещание pg.connect с Bluebird . Я немного изменил это решение.

var Promise = require('bluebird');
var pg = require('pg');
Object.keys(pg).forEach(function (key) {
  var Cls = null;
  try {
    Cls = pg[key];
    if (typeof Cls === 'function') {
      Promise.promisifyAll(Cls.prototype);
      Promise.promisifyAll(Cls);
    }
  } catch (e) {
    console.log(e);
  }
});
Promise.promisifyAll(pg);

здесь 'pg[key] заключен в блок try-catch, потому что pg[key] может перезапустить error при попытке доступа к pg['native']

person Vlad Ankudinov    schedule 25.02.2016