Trying to create a connection in Node.js using the npm light-orm and PostgreSQL (pg) - node.js

I am trying to create a postgreSQL connection using the light-orm.
I have it working in MySQL using:
var mysql = require('mysql'),
lightOrm = require('light-orm');
lightOrm.driver = mysql.createConnection({
host: "localhost",
user: "me",
password: "secret",
database: "test"
});
lightOrm.driver.connect();
However I cannot seem to get it to work with PostgreSQL.
What I have is:
var pg = require('pg'),
lightOrm = require('light-orm');
lightOrm.driver = new pg.Client('postgres://me:secret#localhost/test');
lightOrm.driver.connect();
I know that the connection is happening, because if I change the password to something incorrect, I get an error. But when trying to use the same code that works with MySQL, I either get an error, or nada.
My guess is this problem stems from my lack of knowledge of the pg module and not a light-orm issue.

Related

Render Hosted Postgres database throws ECONNRESET on any connection attempt Node Express App

I am unable to query my Postgres DB in Render. I researched this issue online and found that it was a common problem but none of the solutions I found worked.
Here is my server-side code (I am using NodeJS, Express, Typescript and Postgres)
import postgres, { RowList, Row } from 'postgres'
import appconfig from '../app.config'
type Query = (sql: string) => Promise<RowList<Row[]>>
const query: Query = async (sql) => {
try {
const q = postgres({
host: appconfig.database.host,
port: appconfig.database.port,
database: appconfig.database.schema,
username: appconfig.database.username,
password: appconfig.database.password,
})
const res = await q`${sql}`
return res
} catch (err) {
throw err
}
}
export default query
I receive the following error every time and have not had a successful attempt. It's worth noting I have no issues connecting from PGAdmin on the same PC with the same credentials
Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
at cachedError (C:\Users\xxxxx\repos\one-watch\node_modules\postgres\cjs\src\query.js:171:23)
at new Query (C:\Users\xxxxx\repos\one-watch\node_modules\postgres\cjs\src\query.js:36:24)
at sql (C:\Users\xxxxx\repos\one-watch\node_modules\postgres\cjs\src\index.js:111:11)
at C:\Users\xxxxx\repos\one-watch\src\database\query.ts:15:24
I have never used postgres before, all of my database experience has been in mysql up to this point, although I don't expect this is a postgres problem but potentially just a nuance of Render's implementation of their Postgres service. Any help would be greatly appreciated, thanks!
The only articles I've found like this one are related but they are able to get at least some sort of successful connection at least once. In my case they are all failing.
Adding
?sslmode=no-verify
in the end of the url worked for me.

NodeJS mysql2 - should I handle pool disconnections?

I use mysql2 module in my NodeJS project.
I understand the concept of database pooling in mysql2 module
(https://www.npmjs.com/package/mysql2).
Before using pool, I used regular connection with mysql2.createConnection() function,
but after some time I got 'PROTOCOL_CONNECTION_LOST' error.
My code is:
db.js:
const mysql = require('mysql2');
const pool = mysql.createPool({
host: 'sql server',
user: 'username',
database: 'database',
password: 'pass',
port: 3306,
connectionLimit: 10,
queueLimit: 0
});
module.exports = pool;
And how I using it:
const db = require('db');
db.query(...);
The query() and execute() functions on pool instance automatically call release() function of pool instance, and that is very good (because I don't need to write that command manually after any query).
But I need to understand: if I work like that (with pool, instead of without pool), there is a guarentee
'PROTOCOL_CONNECTION_LOST' will not be thrown? Should I handle that or the pooling mechanism does it automatically?
I ask because I saw on the internet some code that, for example, re-create the connection.
With pool, I need to re-create the connection sometime?
Thanks a lot!

MongoError - Authentication error (password with #)

Here is my code in my NodeJS application, to connect to my MongoDB engine :
const collection = 'mynewcollection';
const password = 'passwordwithan#';
const mongoUrl = `mongodb://admin:${encodeURIComponent(password)}#mymongobase.net/${collection}`;
// Connect using the connection string
MongoClient.connect(mongoUrl, {useNewUrlParser: true}, function(err, db) {
console.log(err.toString())
});
I get an authentication error. I tried several things to handle the '#' character and reading the documentation I thought that it was the good one...
But it is still failing even if the user and password are the good one.
Is the API correctly used ? Do you understand what is wrong ?
Thanks in advance.
OK I found the solution.
If you use :
const mongoUrl = `mongodb://admin:${encodeURIComponent(password)}#mymongobase.net/${collection}`;
Mongo will try to connect with admin/password defined on the collection.
If you don't put the collection in the mongo url :
const mongoUrl = `mongodb://admin:${encodeURIComponent(password)}#mymongobase.net`;
Then you can use the super user defined on all the mongo engine.

What changes are to be made in code to move from Feathers nedb to Postgres?

I have used feathers-nedb library and wrote a server code in Node. Now I need to shift to Postgres DB. I have written models and data insert queries in feathers-nedb so is there way I don't mess up with the structure, but connect to Postgres instead and run the code.
There is a way. You can use the feathers-knex library. Just change the nedb model to feathers-knex and create a Model using knex Postgres connection string.
const dbPath = app.get('nedb');
const Model = new NeDB({
filename: path.join(dbPath, 'test.db'),
autoload: true
});
const Model = new knex({
client: 'pg',
connection: "postgres://postgres:password#localhost:5432/test",
searchPath: ['knex', 'public'],
});
This is the only code change that is required on the Model side. On the service side, instead of feathers-nedb use feathers-knex.

Mongoose with ReplicaSet on Atlas

I have a replica set on MongoDB Atlas and this is my mongo shell connection string which connects perfectly:
$ mongo "mongodb://MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE?replicaSet=MY_REPLICASET-NAME-shard-0" --ssl --username MY_USERNAME --password MY_PASSWORD --authenticationDatabase MY_ADMIN_DATABASE
How Can I convert it to use in mongoose? How Can I build my uri and options variable?
I tried the following without success:
// connection string using mongoose:
var uri = 'mongodb://MY_USER:MY_PASSWORD#' +
'MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE';
var options = {
replset: {
ssl: true,
authSource: 'MY_ADMIN_DATABASE',
rs_name: 'MY_REPLICASET_NAME-shard-0'
}
};
mongoose.connect(uri, options);
var db = mongoose.connection;
I've tried including user: and pass: on options, removing MY_USER:MY_PASSWORD# from uri, change rs_name to replicaSet, every unsuccessful attempt. It seems that mongoose is not considering the authSource option.
Using the mongojs, it works fine with the following code:
// connection string using mongojs:
var uri = 'mongodb://MY_USER:MY_PASSWORD#' +
'MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE';
var options = {
ssl: true,
authSource: 'MY_ADMIN_DATABASE',
replicaSet: 'MY_REPLICASET_NAME-shard-0'
};
var db = mongojs(uri,'', options);
But, I need to use mongoose because the ODM in my project.
How can I build my uri and options variable using mongoose?
ON MONGODB 3.4.x
I resolved this issue putting the 'options' value directly in 'uri' string, according to documentation (http://mongoosejs.com/docs/connections.html) on 'Replica Set Connections' section.
// connection string using mongoose:
var uri = 'mongodb://MY_USER:MY_PASSWORD#' +
'MY_SERVER-shard-00-00-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-01-clv3h.mongodb.net:27017,' +
'MY_SERVER-shard-00-02-clv3h.mongodb.net:27017/MY_DATABASE' +
'ssl=true&replicaSet=MY_REPLICASET_NAME-shard-0&authSource=MY_ADMIN_DATABASE';
mongoose.connect(uri);
var db = mongoose.connection;
Now, it is working fine!
NOTICE WITH MONGODB 3.6
On MongoDB Atlas using the version 3.6.x, the connection string changed to use a DNS server making the link shorter.
mongodb+srv://MY_USER:MY_PASSWORD#MY_SERVER.mongodb.net/MY_DATABASE
...if you use this connection string in your application, this will connect with success but it will be able to read and write only with atlas users with higher privilegies access (atlasAdmin, readWriteAnyDatabase...).
To you work with an specific user with privilege only to readWrite your database, you will need to keep the same connection string used in MongoDB 3.4 because the mongoose not recognized the DNS option (mongodb+srv).
P.S. all the new resources from MongoDB 3.6.x will continue working normally!
Add username and password to database connection
mongodb://[username:password#]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
Standard Connection String Format

Resources