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:
myDb
existeComme 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.
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.
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.
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()
})
Installer
npm install --save -g pgtools
Exemple CLI
createdbjs my_awesome_db --user=admin --password=admin