2016-03-20 21 views
16

Sto costruendo un'applicazione Express che si connette a un database Postgres utilizzando il modulo pg-promise.Verificare la connessione al database con pg-promise all'avvio di un'applicazione

Mi piacerebbe assicurare che la connessione al database abbia esito positivo all'avvio del server delle applicazioni. In altre parole, se la connessione al database fallisce, vorrei lanciare un errore.

Il mio file server.js è la seguente:

const express = require("express"); 

const databaseConfig= { 
    "host": "localhost", 
    "port": 5432, 
    "database": "library_app", 
    "user": "postgres" 
}; 

const pgp = require("pg-promise")({}); 
const db = pgp(databaseConfig); 

const app = express(); 
const port = 5000; 

app.listen(port, (err) => { 
    console.log(`running server on port: ${port}`); 
}); 

La configurazione attuale avviare il Server Express indipendentemente dal fatto che la connessione al database è valido, che non è il comportamento vorrei.

Ho provato a consultare i documenti ma non sono riuscito a trovare una soluzione. Ho anche provato const db = pgp(databaseConfig).catch((err) => { // blow up });, ma questo non ha funzionato perché pgp non restituisce una promessa.

+0

E 'stato risposto qui: https://github.com/vitaly-t/pg-promise/issues/81 –

risposta

30

Sono l'autore di pg-promise;) E questa non è la prima volta che viene posta questa domanda, quindi vi sto dando una spiegazione dettagliata qui.

Quando si crea un'istanza di un nuovo oggetto di database in questo modo:

const db = pgp(connection); 

... tutto ciò che fa - crea l'oggetto, ma non provare a connettersi. La libreria è costruita sulla parte superiore del pool di connessioni e solo i metodi di query effettivi richiedono una connessione dal pool.

From the official documentation:

oggetto db rappresenta il protocollo di database, con connessione al database pigrizia, cioè solo i metodi query effettiva acquisire e rilasciare la connessione. Pertanto, è necessario creare un solo oggetto globale/condiviso db per ogni dettaglio di connessione.

Tuttavia, è possibile chiedere la libreria per la connessione senza eseguire alcuna domanda, utilizzando il metodo connect, come mostrato in seguito.

E anche se questo metodo non è più un metodo consigliato per concatenare le query, dal momento che è stato introdotto il supporto per Tasks (come approccio più sicuro), è comunque utile verificare la connessione in generale.

ho copiato l'esempio dalla mia posta: https://github.com/vitaly-t/pg-promise/issues/81

Di seguito è riportato un esempio di farlo in due modi, allo stesso tempo, in modo da poter scegliere quale approccio si piace di più.

const initOptions = { 
    // global event notification; 
    error: (error, e) => { 
     if (e.cn) { 
      // A connection-related error; 
      // 
      // Connections are reported back with the password hashed, 
      // for safe errors logging, without exposing passwords. 
      console.log('CN:', e.cn); 
      console.log('EVENT:', error.message || error); 
     } 
    } 
}; 

const pgp = require('pg-promise')(initOptions); 

// using an invalid connection string: 
const db = pgp('postgresql://userName:[email protected]:port/database'); 

db.connect() 
    .then(obj => { 
     obj.done(); // success, release the connection; 
    }) 
    .catch(error => { 
     console.log('ERROR:', error.message || error); 
    }); 

Uscite:

CN: postgresql://userName:########@host:port/database EVENT: getaddrinfo ENOTFOUND host host:5432 ERROR: getaddrinfo ENOTFOUND host host:5432

Ogni errore nella libreria è in primo luogo segnalato tramite il gestore globale error eventi, e solo allora l'errore viene segnalato nel corrispondente .catch gestore.

alternativa

Invece di stabilire la connessione manualmente, si può semplicemente eseguire un tipo di query che sarebbe sempre successo per una connessione valida, come la seguente:

db.proc('version') 
    .then(data => { 
     // SUCCESS 
     // data.version = 
     // 'PostgreSQL 9.5.1, compiled by Visual C++ build 1800, 64-bit' 
    }) 
    .catch(error => { 
     // connection-related error 
    }); 

link API:

+0

Grazie @ Vitaly-t per la vostra risposta. Questo e 'esattamente quello che stavo cercando. –

+0

Come si ottiene il pool di connessioni effettivo? C'è una lib di terze parti che vuole una ppol e preferirei non impostare una seconda connessione accanto alla connessione di pg-promessa che ho. – retorquere

+1

@retorquere Quando è stata scritta questa risposta, non esisteva il pool di connessioni. La versione attualmente rilasciata è 5.9.5, che utilizza ancora il driver v5.1, che non ha alcun pool esterno da condividere, ha solo un pool interno globale. Solo la versione 6.x utilizza il driver più recente con il suo pool di connessione, a cui è possibile accedere tramite [db. $ Pool] (http://vitaly-t.github.io/pg-promise/Database.html#.$pool) . –