Comment se connecter à Postgres via Node.js

123

Je me surprends à essayer de créer une base de données postgres, alors j'ai installé postgres et démarré un serveur avec initdb /usr/local/pgsql/data, puis j'ai démarré cette instance avec postgres -D /usr/local/pgsql/datamaintenant comment puis-je interagir avec cela via le nœud? Par exemple, quel serait le connectionstringproblème, ou comment puis-je savoir ce que c'est.

Doboy
la source

Réponses:

313

Voici un exemple que j'ai utilisé pour connecter node.js à ma base de données Postgres.

L'interface de node.js que j'ai utilisée peut être trouvée ici 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();
});

MISE À JOUR: - LA query.onfonction est maintenant obsolète et donc le code ci-dessus ne fonctionnera pas comme prévu. Pour résoudre ce problème, consultez: - query.on n'est pas une fonction

Kuberchaun
la source
24
Voilà le type d'exemple que j'aime voir. Un code clair et inclusif. Merci JustBob.
Stradas
1
Qu'avez-vous ajouté dans votre pg_hba.conf pour autoriser les connexions depuis node.js? Merci
Marius
3
host all all 0.0.0.0/0 md5 Cette entrée permettra, si je me souviens bien, de laisser toute adresse IP se connecter. Gardez à l'esprit que ce n'est pas spécifique au nœud, mais spécifique à PostgreSQL. Également dans postgresql.conf, j'ai listen_addresses = '*'. Pour les configurations de production, veuillez lire la documentation pour vous assurer de ne pas ouvrir de trous nulle part. Je l'utilise dans ma configuration de développement, donc je suis d'accord pour permettre à n'importe quelle machine de se connecter.
Kuberchaun
1
Les paramètres de conString énoncés sont le génie, et exactement ce que je cherchais. Je vous remercie!
nelsonenzo
33

Une approche moderne et simple: 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]);

Voir aussi: Comment déclarer correctement votre module de base de données .

vitaly-t
la source
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change.
arulmr
1
Dans un monde idéal - oui, et pourtant, la réponse acceptée ici, comme vous pouvez le voir ci-dessus - juste le lien aussi. Comme là-bas, il serait tout simplement trop de faire un résumé à partir des informations fournies par le lien, et étant donné que les deux liens sont donnés aux référentiels publics de GitHub, les chances qu'ils disparaissent ne sont pas plus que les chances que StackOverflow disparaisse. .
vitaly-t
Peut-être simplement fournir un exemple simple de son utilisation pour quelque chose de très basique, qui ne devrait prendre que quelques lignes mais serait suffisant pour ne pas en faire un lien uniquement.
Qantas 94 Heavy
@ Qantas94Heavy, et je viens de le faire, suspendez le vote à la baisse :)
vitaly-t
@ vitaly-t: Quelqu'un a probablement signalé le message comme "de très mauvaise qualité", ce qui donne un vote défavorable automatique si le message est modifié ou supprimé avant que le drapeau ne soit traité.
Qantas 94 Heavy
12

Juste pour ajouter une option différente - j'utilise Node-DBI pour me connecter à PG, mais aussi en raison de la possibilité de parler à MySQL et sqlite. Node-DBI inclut également des fonctionnalités pour créer une instruction select, ce qui est pratique pour faire des choses dynamiques à la volée.

Exemple rapide (en utilisant les informations de configuration stockées dans un autre fichier):

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
la source
Hé, mlaccetti, j'ai un problème similaire en essayant de me connecter et d'exécuter des tests sur une base de données SQLite3. Je suis en train de suivre un tutoriel avec des instructions pour utiliser DBWrapper, c'est pourquoi je vous contacte. Ma question est ici: stackoverflow.com/q/35803874/1735836
Patricia
Node-DBI a été abandonné depuis longtemps et n'est plus pris en charge.
vitaly-t
2

Une solution peut utiliser pooldes clients comme les suivants:

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

Vous pouvez voir plus de détails sur cette ressource .

OMG
la source
vous n'avez pas utilisé 'config'.
LEMUEL ADANE
1

Slonik est une alternative aux réponses proposées par Kuberchaun et Vitaly.

Slonik met en œuvre une gestion sûre des connexions ; vous créez un pool de connexions et l'ouverture / la gestion des connexions est gérée pour vous.

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 est votre chaîne de connexion (ou plus canoniquement un URI ou DSN de connexion).

L'avantage de cette approche est que votre script garantit que vous ne laissez jamais accidentellement des connexions suspendues.

Les autres avantages de l'utilisation de Slonik incluent:

Gajus
la source
0

Nous pouvons également utiliser postgresql-easy . Il est construit sur node-postgres et sqlutil . Remarque: pg_connection.js et your_handler.js sont dans le même dossier. db.js se trouve dans le dossier de configuration placé.

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
la source