node-postgres crea il database

Sto usando node-postgres e, all’inizio della mia applicazione, voglio verificare se il database esiste o meno. Quindi l’idea del mio stream di lavoro è la seguente:

  1. Controlla se myDb è esistente
  2. Se è lì, crea i tavoli
  3. In caso contrario, quindi creare prima il database, quindi le tabelle

Come si vede è un processo molto semplice, tuttavia, l’implementazione del driver richiede di avere un nome di database postgres://username:[email protected]/database da connettere, il che significa che è necessario connettersi prima a un database.

Quindi quello che sto facendo ora è connettersi al database di Postgres all’inizio, fare una query per creare un database, inoltrare l’eccezione se è già lì, quindi chiudere la mia connessione e connettermi al database appena creato, quindi creare le tabelle. Ecco il codice:

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

Come vedi, sto aprendo e chiudendo la connessione due volte, e in questo modo mi sembra sbagliato. Sarò felice se tu proporti un modo migliore, o forse spieghi come hai realizzato questo.

Come si vede è un processo molto semplice, tuttavia, l’implementazione del driver richiede di avere un nome di database postgres: // username: password @ host / database da connettere, il che significa che è necessario connettersi prima a un database.

Non è a causa dell’implementazione del driver, è PostgreSQL stesso. È lo stesso con qualsiasi altra lingua o autista.

Un client deve essere connesso a un database per poter fare qualsiasi cosa, incluso un CREATE DATABASE . Oltre al database postgres , template1 viene spesso utilizzato anche per questo scopo.

Quindi, poiché è necessario connettersi al database appena creato per creare oggetti al suo interno, non c’è modo di evitare l’apertura di un’altra connessione.

In breve, quello che stai facendo non può essere semplificato, è già ottimale.

Ho appena scritto un modulo per questo: 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); }); 

Spero che possa rendere il tuo codice un po ‘più pulito.

Questo è un po ‘vecchio ma voglio solo condividere come ho gestito questo tipo di installazione.

Devi chiamare il terzo parametro dal callback che è il done da pg.connect(conn, (err, client, done) => {}) . Questo rilascerà la connessione e tornerà in 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() })