Como fazer a conexão com o Postgres via Node.js

123

Eu me pego tentando criar um banco de dados do postgres, então instalei o postgres e iniciei um servidor com initdb /usr/local/pgsql/data, então iniciei a instância postgres -D /usr/local/pgsql/dataagora como posso interagir com isso através do nó? Por exemplo, o que seria connectionstringou como posso descobrir o que é.

Doboy
fonte

Respostas:

313

Aqui está um exemplo que eu usei para conectar o node.js ao meu banco de dados Postgres.

A interface no node.js que usei pode ser encontrada aqui https://github.com/brianc/node-postgres

var pg = require('pg');
var conString = "postgres://YourUserName:YourPassword@localhost:5432/YourDatabase";

var client = new pg.Client(conString);
client.connect();

//queries are queued and executed one after another once the connection becomes available
var x = 1000;

while (x > 0) {
    client.query("INSERT INTO junk(name, a_number) values('Ted',12)");
    client.query("INSERT INTO junk(name, a_number) values($1, $2)", ['John', x]);
    x = x - 1;
}

var query = client.query("SELECT * FROM junk");
//fired after last row is emitted

query.on('row', function(row) {
    console.log(row);
});

query.on('end', function() {
    client.end();
});



//queries can be executed either via text/parameter values passed as individual arguments
//or by passing an options object containing text, (optional) parameter values, and (optional) query name
client.query({
    name: 'insert beatle',
    text: "INSERT INTO beatles(name, height, birthday) values($1, $2, $3)",
    values: ['George', 70, new Date(1946, 02, 14)]
});

//subsequent queries with the same name will be executed without re-parsing the query plan by postgres
client.query({
    name: 'insert beatle',
    values: ['Paul', 63, new Date(1945, 04, 03)]
});
var query = client.query("SELECT * FROM beatles WHERE name = $1", ['john']);

//can stream row results back 1 at a time
query.on('row', function(row) {
    console.log(row);
    console.log("Beatle name: %s", row.name); //Beatle name: John
    console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
    console.log("Beatle height: %d' %d\"", Math.floor(row.height / 12), row.height % 12); //integers are returned as javascript ints
});

//fired after last row is emitted
query.on('end', function() {
    client.end();
});

ATUALIZAÇÃO: - A query.onfunção agora está obsoleta e, portanto, o código acima não funcionará conforme o esperado. Como uma solução para esta análise: - query.on não é uma função

Kuberchaun
fonte
24
Agora esse é o tipo de exemplo que eu gosto de ver. Limpo e inclusivo de código apenas o suficiente. Obrigado JustBob.
Strada
1
O que você adicionou no seu pg_hba.conf para permitir conexões do node.js? Obrigado
Marius
3
host all all 0.0.0.0/0 md5 Esta entrada irá se bem me lembrar deixar qualquer IP conectar. Lembre-se de que isso não é específico do nó, mas específico do PostgreSQL. Também no postgresql.conf, tenho listen_addresses = '*'. Para configurações de produção, leia os documentos para garantir que você não esteja abrindo furos em lugar nenhum. Eu uso isso na minha configuração de desenvolvimento, por isso estou bem em permitir que qualquer máquina se conecte.
Kuberchaun
1
Os parâmetros de configuração explicitados são geniais e exatamente o que eu estava procurando. Obrigado!
Nelsonenzo 30/07
33

Uma abordagem moderna e simples: pg-promessa :

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

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

// alternative:
// var cn = 'postgres://username:password@host:port/database';

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

// select and return a single user name from id:
db.one('SELECT name FROM users WHERE id = $1', [123])
    .then(user => {
        console.log(user.name); // print user name;
    })
    .catch(error => {
        console.log(error); // print the error;
    });

// alternative - new ES7 syntax with 'await':
// await db.one('SELECT name FROM users WHERE id = $1', [123]);

Consulte também: Como declarar corretamente seu módulo de banco de dados .

vitaly-t
fonte
Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada.
Arulmr 04/04
1
Em um mundo ideal - sim, e ainda assim, a resposta aceita aqui, como você pode ver acima - apenas o link também. Da mesma forma que seria demais, seria demais fazer um resumo das informações fornecidas pelo link e, considerando que os dois links são fornecidos aos repositórios públicos do GitHub, as chances de eles ficarem mortos não são mais do que as chances do StackOverflow ficar morto .
precisa saber é o seguinte
Talvez apenas forneça um exemplo simples de usá-lo para algo muito básico, que deve ocupar apenas algumas linhas, mas seria suficiente para não torná-lo somente para link.
Qantas 94 Heavy
@ Qantas94Heavy, e eu só queria, segure-a para baixo direito a voto :)
Vitaly-t
@ vitaly-t: alguém provavelmente sinalizou a postagem como "qualidade muito baixa", o que dá um voto negativo automático se a postagem for editada ou excluída antes da manipulação da bandeira.
Qantas 94 Heavy
12

Apenas para adicionar uma opção diferente - eu uso o Node-DBI para conectar ao PG, mas também devido à capacidade de conversar com MySQL e sqlite. O Node-DBI também inclui funcionalidade para criar uma instrução select, útil para fazer coisas dinâmicas em tempo real.

Amostra rápida (usando informações de configuração armazenadas em outro arquivo):

var DBWrapper = require('node-dbi').DBWrapper;
var config = require('./config');

var dbConnectionConfig = { host:config.db.host, user:config.db.username, password:config.db.password, database:config.db.database };
var dbWrapper = new DBWrapper('pg', dbConnectionConfig);
dbWrapper.connect();
dbWrapper.fetchAll(sql_query, null, function (err, result) {
  if (!err) {
    console.log("Data came back from the DB.");
  } else {
    console.log("DB returned an error: %s", err);
  }

  dbWrapper.close(function (close_err) {
    if (close_err) {
      console.log("Error while disconnecting: %s", close_err);
    }
  });
});

config.js:

var config = {
  db:{
    host:"plop",
    database:"musicbrainz",
    username:"musicbrainz",
    password:"musicbrainz"
  },
}
module.exports = config;
mlaccetti
fonte
Ei, mlaccetti, tenho um problema semelhante ao tentar conectar e executar testes em um banco de dados SQLite3. Estou passando por um tutorial com instruções para usar o DBWrapper, e é por isso que estou entrando em contato com você. Minha pergunta está aqui: stackoverflow.com/q/35803874/1735836
Patricia
O Node-DBI foi abandonado desde então e não é mais suportado.
vitaly-t
2

Uma solução pode ser usar poolclientes como o seguinte:

const { Pool } = require('pg');
var config = {
    user: 'foo', 
    database: 'my_db', 
    password: 'secret', 
    host: 'localhost', 
    port: 5432, 
    max: 10, // max number of clients in the pool
    idleTimeoutMillis: 30000
};
const pool = new Pool(config);
pool.on('error', function (err, client) {
    console.error('idle client error', err.message, err.stack);
});
pool.query('SELECT $1::int AS number', ['2'], function(err, res) {
    if(err) {
        return console.error('error running query', err);
    }
    console.log('number:', res.rows[0].number);
});

Você pode ver mais detalhes sobre este recurso .

AMD
fonte
você não usou 'config'.
LEMUEL ADANE
1

Slonik é uma alternativa às respostas propostas por Kuberchaun e Vitaly.

Slonik implementa manipulação segura de conexão ; você cria um pool de conexões e a abertura / manipulação da conexão é tratada por você.

import {
  createPool,
  sql
} from 'slonik';

const pool = createPool('postgres://user:password@host:port/database');

return pool.connect((connection) => {
  // You are now connected to the database.
  return connection.query(sql`SELECT foo()`);
})
  .then(() => {
    // You are no longer connected to the database.
  });

postgres://user:password@host:port/database é sua cadeia de conexão (ou mais canonicamente, um URI ou DSN de conexão).

O benefício dessa abordagem é que seu script garante que você nunca saia acidentalmente de conexões suspensas.

Outros benefícios do uso do Slonik incluem:

Gajus
fonte
0

Também podemos usar o postgresql-easy . Ele é construído no node-postgres e no sqlutil . Nota: pg_connection.js e your_handler.js estão na mesma pasta. O db.js está na pasta de configuração colocada.

pg_connection.js

const PgConnection = require('postgresql-easy');
const dbConfig = require('./config/db');
const pg = new PgConnection(dbConfig);
module.exports = pg;

./config/db.js

module.exports =  {
  database: 'your db',
  host: 'your host',
  port: 'your port',
  user: 'your user',
  password: 'your pwd',
}

your_handler.js

  const pg_conctn = require('./pg_connection');

  pg_conctn.getAll('your table')
    .then(res => {
         doResponseHandlingstuff();
      })
    .catch(e => {
         doErrorHandlingStuff()     
      })
Naveen Karnam
fonte