web-dev-qa-db-fra.com

node-postgres crée une base de données

J'utilise node-postgres et, au début de mon application, je veux vérifier si la base de données existe ou non. Donc, mon idée de workflow est la suivante:

  1. Vérifier si myDb existe
  2. Si c'est le cas, créez les tables
  3. Sinon, créez d'abord la base de données, puis les tables

Comme vous le voyez, le processus est très simple. Cependant, la mise en œuvre du pilote nécessite la connexion d’un nom de base de données postgres://username:password@Host/database, ce qui signifie que vous devez d’abord vous connecter à une base de données. 

Donc, ce que je fais maintenant, c'est de me connecter à la base de données postgres au début, de lancer une requête pour créer une base de données, d'exécuter l'exception si elle existe déjà, puis de fermer ma connexion et de me connecter à la base de données nouvellement créée, puis de créer les tables. Voici le code:

var conStringPri = 'postgres://' + username + ':' + password + '@' + Host + 
    '/postgres';
var conStringPost = 'postgres://' + username + ':' + password + '@' + Host + 
    '/' + dbName;

pg.connect(conStringPri, function(err, client, done) { // connect to postgres db
    if (err)
        console.log('Error while connecting: ' + err); 
    client.query('CREATE DATABASE ' + dbName, function(err) { // create user's db
        if (err) 
            console.log('ignoring the error'); // ignore if the db is there
        client.end(); // close the connection

        // create a new connection to the new db
        pg.connect(conStringPost, function(err, clientOrg, done) {
            // create the table
            clientOrg.query('CREATE TABLE IF NOT EXISTS ' + tableName + ' ' +
                    '(...some sql...)';
        });
    });
});

Comme vous le voyez, j'ouvre et ferme la connexion deux fois, et cette voie me semble fausse. Je serai heureux si vous proposez un meilleur moyen, ou peut-être expliquer comment vous avez accompli cela.

18
anvarik

Comme vous le voyez, le processus est très simple, cependant, la mise en œuvre du pilote Nécessite un nom de base de données Postgres: // nomutilisateur: mot de passe @ hôte/base de données à connecter, auquel signifie que vous devez d'abord vous connecter à une base de données.

Ce n'est pas à cause de l'implémentation du pilote, c'est PostgreSQL lui-même. C'est la même chose avec n'importe quelle autre langue ou pilote.

Un client doit être connecté à une base de données pour pouvoir exécuter quoi que ce soit, y compris un CREATE DATABASE. En plus de la base de données postgres, template1 est souvent utilisé à cette fin.

Ensuite, comme vous devez vous connecter à la base de données fraîchement créée pour créer des objets à l'intérieur de celle-ci, il est impossible d'éviter d'ouvrir une autre connexion.

En bref, ce que vous faites ne peut être simplifié, c'est déjà optimal.

13
Daniel Vérité

Je viens d'écrire un module pour ça: https://github.com/olalonde/pgtools

var pgtools = require('pgtools');
pgtools.createdb({
  user: 'postgres',
  password: 'some pass',
  port: 5432,
  Host: 'localhost'
}, 'test-db', function (err, res) {
  if (err) {
    console.error(err);
    process.exit(-1);
  }
  console.log(res);
});

Espérons que cela rendra votre code un peu plus propre.

7
Olivier Lalonde

C'est un peu vieux mais je veux juste partager comment j'ai géré ce genre de configuration.

Vous devez appeler le troisième paramètre à partir du rappel qui est la done à partir de pg.connect(conn, (err, client, done) => {}). Cela libérera la connexion et ramènera au pool.

 async.series([
   done => {
     pg.connect(connPrimary, (err, client, releaseConn) => {
      if (err) return done(err)

      client.query(`CREATE DATABASE ${conf.database}`, (err) => {
        if (err && !~err.message.indexOf('already exists')) {
          return done(err)
        }

        client.end()
        releaseConn()
        done()
      })
    })
  },
  done => {
    let connSecondary = `postgres://${conf.user}:${conf.password}@${conf.Host}:${conf.port}/${conf.database}`

    pg.connect(connSecondary, (err, client, releaseConn) => {
      if (err) return done(err)

      let createTableQuery = `CREATE TABLE IF NOT EXISTS test_table(_id bigint primary key, co2_field varchar(40) NOT NULL, temp_field int NOT NULL, quality_field decimal NOT NULL, reading_time_field timestamp NULL)`

      client.query(createTableQuery, err => {
        if (err) return done(err)

        releaseConn()
        done()
      })
    })    
  }
], err => {
  should.ifError(err)
  doneInit()
})
3
Redd.o

Installer

npm install --save -g pgtools

Exemple CLI

createdbjs my_awesome_db --user=admin --password=admin
0
аlex dykyі