Verifique la conexión de la base de datos con pg-promise al iniciar una aplicación

Estoy creando una aplicación Express que se conecta a una base de datos de Postgres utilizando el módulo pg-promise .

Me gustaría asegurarme de que la conexión a la base de datos sea exitosa al iniciar el servidor de aplicaciones. En otras palabras, si la conexión a la base de datos falla, me gustaría lanzar un error.

Mi archivo server.js es el siguiente:

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 configuración actual iniciará el servidor Express independientemente de si la conexión de la base de datos es válida, lo cual no es el comportamiento que me gustaría.

Intenté navegar por los documentos, pero no pude encontrar una solución. También probé const db = pgp(databaseConfig).catch((err) => { // blow up }); , pero eso no funcionó porque pgp no devuelve una promesa.

Soy el autor de pg-promise 😉 Y esta no es la primera vez que se hace esta pregunta, así que aquí le doy una explicación detallada.

Cuando creas un nuevo objeto de base de datos como este:

 const db = pgp(connection); 

… todo lo que hace – crea el objeto, pero no intenta conectarse. La biblioteca se construye sobre el grupo de conexiones, y solo los métodos de consulta reales solicitan una conexión del grupo.

De la documentación oficial :

El objeto db representa el protocolo de la base de datos, con una conexión de base de datos lenta, es decir, solo los métodos de consulta reales adquieren y liberan la conexión. Por lo tanto, debe crear solo un objeto db global / compartido por detalles de conexión.

Sin embargo, puede pedir a la biblioteca que se conecte sin ejecutar ninguna consulta, utilizando el método connect , como se muestra más adelante.

Y si bien este método ya no es una forma recomendada para encadenar consultas, desde que se introdujo el soporte para Tareas (como un enfoque más seguro), todavía resulta útil comprobar la conexión en general.

Copié el ejemplo de mi propia publicación: https://github.com/vitaly-t/pg-promise/issues/81

A continuación se muestra un ejemplo de hacerlo de dos maneras al mismo tiempo, para que pueda elegir el enfoque que más le guste.

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

Salidas:

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

Cada error en la biblioteca se informa primero a través del controlador de eventos de error global, y solo entonces se informa el error dentro del controlador .catch correspondiente.

Alternativa

En lugar de establecer la conexión manualmente, simplemente puede ejecutar un tipo de consulta que siempre tendría éxito para una conexión válida, como la siguiente:

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

Enlaces API:

  • Método proc
  • Método de conexión
  • Error de evento