Come connettersi a Postgres tramite Node.js


123

Mi trovo a provare a creare un database postgres, quindi ho installato postgres e avviato un server con initdb /usr/local/pgsql/data, quindi ho avviato quell'istanza con postgres -D /usr/local/pgsql/dataora come posso interagire con questo tramite il nodo? Ad esempio, quale sarebbe connectionstringo come faccio a scoprire di cosa si tratta.

Risposte:


313

Ecco un esempio che ho usato per connettere node.js al mio database Postgres.

L'interfaccia in node.js che ho usato può essere trovata qui 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();
});

AGGIORNAMENTO: - LA query.onfunzione è ora deprecata e quindi il codice sopra non funzionerà come previsto. Come soluzione per questo aspetto: - query.on non è una funzione


24
Questo è il tipo di esempio che mi piace vedere. Chiaro e comprensivo di codice appena sufficiente. Grazie JustBob.
Stradas

1
Cosa hai aggiunto nel tuo pg_hba.conf per consentire le connessioni da node.js? Grazie
Marius

3
host all all 0.0.0.0/0 md5 Se non ricordo male, questa voce consentirà a qualsiasi IP di connettersi. Tieni presente che questo non è specifico del nodo, ma specifico di PostgreSQL. Anche in postgresql.conf ho listen_addresses = '*'. Per le impostazioni di produzione, leggere i documenti per assicurarsi di non aprire buchi da nessuna parte. Lo uso nella mia configurazione di sviluppo, quindi sto bene nel consentire a qualsiasi macchina di connettersi.
Kuberchaun

1
I parametri di conString enunciati sono geniali e proprio quello che stavo cercando. Grazie!
nelsonenzo


33

Un approccio moderno e semplice: pg-promise :

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]);

Vedi anche: Come dichiarare correttamente il modulo del database .


Sebbene questo collegamento possa rispondere alla domanda, è meglio includere le parti essenziali della risposta qui e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
arulmr

1
In un mondo ideale - sì, eppure, la risposta accettata qui, come puoi vedere sopra - anche solo il link. Allo stesso modo, sarebbe semplicemente troppo fare un abstract dalle informazioni fornite dal collegamento e, considerando che entrambi i collegamenti sono forniti ai repository pubblici di GitHub, le possibilità che vadano morti non sono superiori alle possibilità che StackOverflow vada morto .
vitaly-t

Forse fornisci solo un semplice esempio di utilizzo per qualcosa di molto semplice, che dovrebbe occupare solo poche righe ma sarebbe sufficiente per non renderlo solo link.
Qantas 94 Heavy

@ Qantas94Heavy, e l'ho appena fatto, aspetta il voto
negativo

@ vitaly-t: qualcuno probabilmente ha contrassegnato il post come di "qualità molto bassa", il che fornisce un voto negativo automatico se il post viene modificato o eliminato prima che il flag venga gestito.
Qantas 94 Heavy

12

Solo per aggiungere un'opzione diversa: utilizzo Node-DBI per connettermi a PG, ma anche per la possibilità di parlare con MySQL e sqlite. Node-DBI include anche funzionalità per creare un'istruzione select, utile per eseguire operazioni dinamiche al volo.

Esempio rapido (utilizzando le informazioni di configurazione memorizzate in un altro file):

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;

Ehi, mlaccetti, ho un problema simile cercando di connettermi ed eseguire test su un database SQLite3. Sto seguendo un tutorial con le istruzioni per utilizzare DBWrapper, motivo per cui ti sto contattando. La mia domanda è qui: stackoverflow.com/q/35803874/1735836
Patricia

Node-DBI è stato abbandonato da tempo e non è più supportato.
vitaly-t

2

Una soluzione può essere l'utilizzo pooldi client come il seguente:

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);
});

Puoi vedere maggiori dettagli su questa risorsa .


non hai usato "config".
LEMUEL ADANE

1

Slonik è un'alternativa alle risposte proposte da Kuberchaun e Vitaly.

Slonik implementa la gestione sicura delle connessioni ; si crea un pool di connessioni e l'apertura / gestione della connessione viene gestita automaticamente.

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 è la stringa di connessione (o più canonicamente un URI o DSN di connessione).

Il vantaggio di questo approccio è che il tuo script ti assicura di non lasciare mai accidentalmente connessioni sospese.

Altri vantaggi dell'utilizzo di Slonik includono:


0

Possiamo anche usare postgresql-easy . È costruito su node-postgres e sqlutil . Nota: pg_connection.js e your_handler.js si trovano nella stessa cartella. db.js si trova nella cartella config posizionata.

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()     
      })
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.