Verificar a ligação à base de dados com o pg-promise ao iniciar uma aplicação

estou a construir uma aplicação Expressa que se liga a uma base de dados postgres usando o Módulo pg-promise.

gostaria de assegurar que a ligação à base de dados seja bem sucedida ao iniciar o servidor de aplicações. Por outras palavras, se a ligação à base de dados falhar, gostaria de lançar um erro.

O meu servidor.js file é o seguinte:

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

a configuração actual irá iniciar o servidor expresso , independentemente de se a base de dados a ligação é válida, o que não é o comportamento que eu gostaria.

Tentei ver os documentos, mas não encontrei uma solução. Eu também tentei const db = pgp(databaseConfig).catch((err) => { // blow up });, mas isso não funcionou porque pgp não retorna uma promessa.

Author: vitaly-t, 2016-03-21

1 answers

Eu sou o autor de PG-promise {[[10]};) e esta não é a primeira vez que esta pergunta é feita, por isso estou a dar-lhe uma explicação detalhada aqui.

Quando instanciar um novo objecto de base de dados como este:

const db = pgp(connection);

...tudo o que faz - cria o objeto, mas não tenta se conectar. A Biblioteca é construída sobre o pool de conexão, e apenas os métodos de consulta atuais solicitam uma conexão do pool.

Do funcionário documentação:

O objecto db representa o protocolo da base de dados, com ligação preguiçosa à base de dados, ou seja, apenas os métodos de consulta actuais adquirem e libertam a ligação. Portanto, você deve criar apenas um objeto global / compartilhado db por detalhes de conexão.

No entanto, você pode pedir à biblioteca para se ligar sem executar qualquer consulta, usando o método connect, Como mostrado mais adiante.

E embora este método já não seja uma forma recomendada de perguntas em cadeia, desde que o suporte para as tarefas foi introduzido (como uma abordagem mais segura), ainda é útil verificar a conexão em geral.

Copiei o exemplo do meu próprio post: https://github.com/vitaly-t/pg-promise/issues/81

Abaixo está um exemplo de fazê-lo de duas maneiras ao mesmo tempo, para que você possa escolher a abordagem que você gosta mais.

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:password@host:port/database');

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

Saídas:

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

Todos os erros na biblioteca são primeiro reportado através do global error , e só então o erro é reportado dentro do correspondente .catch handler.

Alternativa

Em vez de estabelecer a ligação manualmente, pode simplesmente executar um tipo de consulta que teria sempre sucesso para uma ligação válida, como a seguinte:

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

Ligações da API:

 35
Author: vitaly-t, 2018-08-24 14:41:52