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ę?
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? Usepg.connect
set thepg.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życieLISTEN/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.
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.
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ę.
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();
});
}
});
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'
}
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()
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