Jaki jest właściwy sposób korzystania z węzła.moduł js postgresql?

Piszę węzeł.aplikacja js na Heroku i korzystanie z modułu PG . Nie mogę znaleźć "właściwego" sposobu, aby uzyskać obiekt klienta dla każdego żądania, które muszę odpytywać bazę danych.

Dokumentacja używa kodu w następujący sposób:

pg.connect(conString, function(err, client) {
  // Use the client to do things here
});

Ale na pewno nie musisz wywoływać pg.connect wewnątrz każdej funkcji używającej bazy danych, prawda? Widziałem inny kod {[5] } który robi to:

var conString = process.env.DATABASE_URL || "tcp://postgres:1234@localhost/postgres";
var client = new pg.Client(conString);
client.connect();
// client is a global so you can use it anywhere now

Skłaniam się ku drugiej opcji, ponieważ wierzę, że wolna instancja bazy danych dla Heroku i tak jest ograniczone do jednego połączenia, ale czy są jakieś wady robienia tego w ten sposób? Czy muszę sprawdzać, czy mój obiekt klienta jest nadal podłączony za każdym razem, zanim go użyję?

Author: Philip, 2011-12-13

6 answers

Jestem autorem node-postgres. Po pierwsze, przepraszam, że dokumentacja nie wyjaśniła właściwej opcji: to moja wina. Postaram się to poprawić. Napisałem Gist właśnie teraz, aby to wyjaśnić, ponieważ rozmowa wzrosła zbyt długo dla Twittera.

Używanie pg.connect jest sposobem na przejście w środowisku sieciowym.

Serwer PostgreSQL może obsłużyć tylko 1 zapytanie na raz na połączenie. Oznacza to, że jeśli masz 1 globalny new pg.Client() połączony z Twoim backend całej aplikacji jest bottleknecked na podstawie jak szybko postgres może odpowiadać na zapytania. Dosłownie ustawia wszystko w kolejce każde zapytanie. Tak, to jest asynchroniczne i tak jest w porządku...ale czy nie raczej pomnożyć przepustowość przez 10x? Use pg.connect set the pg.defaults.poolSize do czegoś zdrowego (robimy 25-100, nie jesteśmy pewni prawidłowy numer jeszcze).

new pg.Client jest na czas, kiedy wiesz, co robisz. Kiedy potrzebujesz jeden długoletni klient dla niektórych powód lub trzeba bardzo ostrożnie kontroluj cykl życia. Dobrym tego przykładem jest użycie LISTEN/NOTIFY. Słuchający klient musi być w pobliżu i podłączony i nie współdzielony, dzięki czemu może prawidłowo obsługiwać NOTIFY wiadomości. Innym przykładem może być otwarcie klienta 1-off, aby zabić niektóre zawieszone rzeczy lub w skryptach wiersza poleceń.

Bardzo pomocną rzeczą jest scentralizowanie całego dostępu do bazy danych w aplikacji do jednego pliku. Nie zaśmiecaj połączeń ani nowych klientów. Mieć plik db.js, który wygląda mniej więcej tak:

module.exports = {
   query: function(text, values, cb) {
      pg.connect(function(err, client, done) {
        client.query(text, values, function(err, result) {
          done();
          cb(err, result);
        })
      });
   }
}

W ten sposób możesz zmienić swoją implementację z pg.connect na niestandardową pulę klientów lub cokolwiek innego i tylko zmienić rzeczy w jednym miejscu.

Spójrz na node-pg-query moduł który właśnie to robi.

 137
Author: brianc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-16 20:22:24

Jestem autorem PG-promise , który upraszcza użycie node-postgres poprzez promises.

Rozwiązuje problemy dotyczące właściwego sposobu łączenia się i odłączania od bazy danych, wykorzystując pulę połączeń zaimplementowaną przez node-postgres , między innymi, jak zautomatyzowane transakcje.

Indywidualne żądanie w PG-promise sprowadza się tylko do tego, co jest istotne dla Twojej logiki biznesowej:

db.any('SELECT * FROM users WHERE status = $1', ['active'])
    .then(data => {
        console.log('DATA:', data);
    })
    .catch(error => {
        console.log('ERROR:', error);
    });

Tzn. nie musisz radzić sobie z logiką połączenia podczas wykonywania zapytań, ponieważ skonfigurowałeś połączenie tylko raz, globalnie, jak to:

const pgp = require('pg-promise')(/*options*/);

const cn = {
    host: 'localhost', // server name or IP address;
    port: 5432,
    database: 'myDatabase',
    user: 'myUser',
    password: 'myPassword'
};
// alternative:
// const cn = 'postgres://username:password@host:port/database';

const db = pgp(cn); // database instance;

O wiele więcej przykładów można znaleźć w Learn by Example tutorial, lub na stronie głównej projektu.

 20
Author: vitaly-t,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-25 16:43:12

Jak widać z Dokumentacji obie opcje są ważne, więc wybierz dowolną opcję. Jako ty, wybrałbym drugą opcję.

 0
Author: alessioalex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 08:23:43

Lepiej jest utworzyć PG pool globalnie i za każdym razem, gdy musisz wykonać operację db, użyj klienta, a następnie zwolnij go z powrotem do puli. Po wykonaniu wszystkich operacji db Zakończ pulę używając pool.end()

Przykładowy kod-

let pool = new pg.Pool(dbConfig);
pool.connect(function(err, client, done) {

if (err) {
    console.error('Error connecting to pg server' + err.stack);
    callback(err);
} else {
    console.log('Connection established with pg db server');

    client.query("select * from employee", (err, res) => {

            if (err) {
                console.error('Error executing query on pg db' + err.stack);
                callback(err);
            } else {
                console.log('Got query results : ' + res.rows.length);


               async.each(res.rows, function(empRecord) {   
                        console.log(empRecord.name);
                });
            }
            client.release();

        });
}

});  

Źródło

 0
Author: Aniket Thakur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-26 19:01:29

Byłem zainteresowany bardzo prostym opiekunem do tego, więc zrobiłem swój własny, nie komplikując tego. Nie mam złudzeń, że jest super podstawowy, ale może pomóc niektórym zacząć. Zasadniczo łączy się, uruchamia zapytania i obsługuje błędy.

function runQuery(queryString, callback) {
  // connect to postgres database
  pg.connect(postgresDatabase.url,function(err,client,done) {
    // if error, stop here
    if (err) {console.error(err); done(); callback(); return;}
    // execute queryString
    client.query(queryString,function(err,result) {
      // if error, stop here
      if (err) {console.error(err+'\nQuery: '+queryString); done(); callback(); return;}
      // callback to close connection
      done();
      // callback with results
      callback(result.rows);
    });
  });
}

Wtedy użyłbyś nazywając to w ten sposób:

runQuery("SELECT * FROM table", function(result) {
  // Whatever you need to do with 'result'
}
 -1
Author: JM-AGMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-19 20:41:38

Oto Jak to robię, coś w rodzaju "całego powyższego podejścia"

Promise = require 'bluebird'
pg = module.exports = require 'pg'

Promise.promisifyAll pg.Client.prototype
Promise.promisifyAll pg.Client
Promise.promisifyAll pg.Connection.prototype
Promise.promisifyAll pg.Connection
Promise.promisifyAll pg.Query.prototype
Promise.promisifyAll pg.Query
Promise.promisifyAll pg

connectionString = process.env.DATABASE_URL

module.exports.queryAsync = (sql, values) ->
  pg.connectAsync connectionString
  .spread (connection, release) ->
    connection.queryAsync sql, values
    .then (result) ->
      console.log result.rows[0]
    .finally ->
      release()
 -2
Author: Duane Fields,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-02 01:58:32