how to disconnect a pool in pg module - node.js

So, I use the pg module in node 8.11.1 / express 4.16.3 / pg 7.4.2
I try to use the pool for my front-end (just selects) and the examples are somewhat confusing.
In connecting it uses just a new Pool and then it shows that I have to do pool.end()
const pool = new Pool({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 3211,
})
pool.query('SELECT NOW()', (err, res) => {
console.log(err, res)
pool.end()
})
I made my code like that and it prints Error: Cannot use a pool after calling end on the pool If I do the same query a couple of times. So, no pool.end()
In queries there is no disconnection in the examples (?)
I finally made my code like the pooling. It shows the pool.on('error', (err, client) => { function and then it uses client.release() in the pool, since "pool.query delegates directly to client.query internally" I guess?
So, what is the right way to use pool in the pg and how to disconnect after each query or failure? I came up with this
const pool = new pg.Pool({
user: 'user',
host: 'localhost',
database: 'myProject',
password: 'secret',
port: 5432
});
pool.on('error', (err, client) => {
console.error('error on client', err, 'on client' , client);
process.exit(-1);
});
app.get('/', (req, res)=>{
pool.connect()
.then(client => {
return client.query('select name from table')
.then(resolved => {
client.release();
res.render('index',{'testData': resolved.rows});
})
.catch(e => { //return client.query
client.release();
res.render('index',{'errorData': e});
})
.catch(e => { //pool.connect()
client.release();
res.render('index',{'errorData': e});
})
})
});
I dont know if this can be shorter in any way. Like, for example if the catch(e => { ////pool.connect()... is needed or it is covered by pool.on('error', (err, client) => {...
Also, it could be a lot sorter if it was like
const pool = new pg.Pool({
user: 'user',
host: 'localhost',
database: 'myProject',
password: 'secret',
port: 5432
});
app.get('/', (req, res)=>{
pool.query('...')
.then(resolved => {
pool.end();// pool disconnect ???
res.render('index',{
'testData': resolved.rows
});
})
.catch(e => {
pool.end();// pool disconnect ???
res.render('index',{
'testData': e
});
})
});
But I dont know if this is right because there is no pool.connect , there is no client returned from that connection and there is no function to disconnect the pool (only to end it, that ends up again with Error: Cannot use a pool after calling end on the pool).
Please advice on the right pool usage and syntax
Thanks

I ran into this kind of Problem too with another npm package for mssql.
After some trail and error i decided to go for a singelton (static would also be possible) class which handles the connection.
Now you just have to call one function before each query in order to create a new connection pool or receive the present one.
Something like this:
let _this = {};
let connectionPool = null;
function getConnection(){
if(connectionPool){
return connectionPool
} else {
connectionPool = new pg.Pool({
user: 'user',
host: 'localhost',
database: 'myProject',
password: 'secret',
port: 5432
});
return connectionPool;
}
}
function closeConnection(){
// close connection here
}
_this.getConnection = getConnection;
_this.closeConnection = closeConnection;
module.exports = _this;

Related

Error when trying to perform postgres queries (triggerUncaughtException(err, true /* fromPromise */);

I was trying to perform postgres queries using node but for some reason is not fetching the data from postgres.
See my database.js below:
const { Client } = require('pg');
const PORT = process.env.PORT || 3000;
const client = new Client({
host: 'localhost',
port: PORT,
user: 'postgres',
password: 'postgres',
database: 'ecommerce'
})
client.connect();
client.query('select * from customers', (err, result) => {
if (!err) {
console.log(result.rows)
} else {
console.log(err)
}
client.end();
})
Please note that the customers table is a valid table in my ecommerce database.
Any help would be appreciated.
You should wait the client to connect.
See the docs here
const { Client } = require('pg')
const client = new Client()
client
.connect()
.then(() => console.log('connected'))
.catch(err => console.error('connection error', err.stack))
Instead of console.log('connected'), write your query.

Connection getting skipped when connecting to Postgress DB

I'm writing a lambda function to connect to a postgress DB that I have on an EC2 instance. I've been utilizing the 'pg' library for connecting as found in their documentation, however, my function keeps skipping over the establish connection piece of my method and just continuing and exiting without accomplishing anything.
const client = new Client({
user: 'user',
host: 'xxxx.xxx.xxxx',
database: 'dbname',
password: 'password',
port: 5432,
})
client.connect(err => {
if (err) {
console.error('connection error', err.stack)
} else {
console.log('connected')
}
})
client.query('select count(*) from "Product"', (error, results) => {
if (error) {
console.log("Error when trying to query");
throw error
}
console.log(results.rows)
})
I'm going exactly by the methods that the 'pg' documentation says (https://node-postgres.com/features/connecting), but can't figure out what is going wrong here. I'm using serverless with nodejs12.x for this function.
You are not waiting for the connection to be established before querying. Try this:
const client = new Client({
user: 'user',
host: 'xxxx.xxx.xxxx',
database: 'dbname',
password: 'password',
port: 5432,
})
return client.connect(err => {
if (err) {
console.error('connection error', err.stack)
} else {
console.log('connected')
return client.query('select count(*) from "Product"', (error, results) => {
if (error) {
console.log("Error when trying to query");
throw error
}
console.log(results.rows)
})
}
})
Although, if your can, create a promise chain as it is probably easier to manage like so:
const client = new Client({
user: 'user',
host: 'xxxx.xxx.xxxx',
database: 'dbname',
password: 'password',
port: 5432,
})
return client.connect().then(()=>{
return client.query('select count(*) from "Product"')
}).then((results)=>{
console.log(results.rows)
}).catch((err)=>{
console.error('error', err.stack? err.stack : err)
})
I say use a promise chain if you can because Im not sure what the pg library returns on connect and query..
Hope this helps!

Sequelize authenticate() does not return any result

I am using Sequelize with postgres database.
But authenticate() function does not send any response(whether it is success or failed)
Here is my code.
const connection = new Sequelize('BLIG', 'postgres', 'admin', {
host: 'localhost',
dialect: 'postgres',
define: {
timestamps: false
}
});
app.use('/', (req, res, next) => {
console.clear();
connection.authenticate()
.then(
() => { console.log("Database connected..."), next() },
error=>{console.log("Database connection error",error)}
)
.catch(err => { console.log('database connection error', err), res.redirect('/error') });
})
If anyone knows this issue, help me please.
update your "pg" node package to 8.5.1 or above version using
npm i pg#8.5.1

What is the fastest way to connect to a database from the web front end?

For example, in the following code (using node-postgres), we connect to the client, query and then end.
const { Pool, Client } = require('pg')
const pool = new Pool({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 3211,
})
pool.query('SELECT NOW()', (err, res) => {
console.log(err, res)
pool.end()
})
const client = new Client({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 3211,
})
client.connect()
client.query('SELECT NOW()', (err, res) => {
console.log(err, res)
client.end()
})
Does that mean we should create a connection each time we intend to query the database ? Is there a faster way ?
Would you suggest using something besides node-postgres?
I will suggest sequelize ORM so you will don't need to worry about other database operation. It also supports PostgreSQL and will maintain and end connection for you its mean just need to create connection and Sequelize will do remaining for you boom it's amazing.
Sequelize is a promise-based ORM for Node.js v4 and up. It supports the dialects PostgreSQL, MySQL, SQLite and MSSQL and features solid transaction support, relations, read replication and more.
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'|'sqlite'|'postgres'|'mssql',
pool: {
max: 5,
min: 0,
idle: 10000
},
// SQLite only
storage: 'path/to/database.sqlite'
});
// Or you can simply use a connection uri
const sequelize = new Sequelize('postgres://user:pass#example.com:5432/dbname');
You can use the .authenticate() function like this to test the connection.
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
For more detail http://docs.sequelizejs.com/

Am I doing connection pooling correctly? Using node-postgres library

I am reading the documentation and trying to figure out connection pooling.
The documentation says that the pool should be long lived, so I have created a config/db.js file where I create pool and export it:
/* src/config/db.js */
const pg = require('pg');
const dbConfig = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_DATABASE,
max: 25,
idleTimeoutMillis: 5000
};
const pool = new pg.Pool(dbConfig);
module.exports = {
pool
};
I have a bunch of routes and controllers. For example, I have /markers endpoint which has a few methods in the controller. In the controller file, I am importing pool from the config/db.js and using it. Is that OK?
const pool = require('../config/db').pool;
const create = function (req, res, next) {
const data = {
created_by: req.body.createdBy,
title: req.body.title,
description: req.body.description,
lat: req.body.lat,
lng: req.body.lng
};
pool.connect((err, client, done) => {
if (err) {
done();
// console.log(err);
return res.status(500).json({ success: false, data: err });
}
client.query(
'INSERT INTO markers(created_by, title, description, lat, lng, geography)\
values($1, $2, $3, $4::decimal, $5::decimal, ST_SetSRID(ST_MakePoint($5::decimal, $4::decimal), $6))',
[
data.created_by,
data.title,
data.description,
data.lat,
data.lng,
4326
],
function(err, res) {
done();
if (err) {
// console.log(err);
}
}
);
return res.status(200).json({ success: true });
});
};
Also, how do I check that the insert was successful so that I don't just return a 200 success if there's no error without knowing if the insert was successful?
that's correct.
as for checking error, you can see right there in the callback where you check if (err), in case no err is return, that mean the insertion is success.

Resources