38

I am building an express application that connects to a postgres database using the pg-promise module.

I would like to ensure that the database connection is successful when starting the application server. In other words, if the connection to the database fails, I'd like to throw an error.

My server.js file is as follows:

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

The current configuration will start the express server regardless of whether the database connection is valid, which is not the behavior I would like.

I tried browsing the docs but couldn't find a solution. I also tried

const db = pgp(databaseConfig).catch((err) => { // blow up });

but that didn't work because pgp does not return a promise.

4

2 回答 2

81

我是pg-promise的作者;)这不是第一次被问到这个问题,所以我在这里给出一个详细的解释。

当您像这样实例化一个新的数据库对象时:

const db = pgp(connection);

...它所做的一切 - 创建对象,但它不尝试连接。该库建立在连接池之上,只有实际的查询方法从池中请求连接。

从官方文档

Objectdb表示数据库协议,具有惰性数据库连接,即只有实际的查询方法获取和释放连接。db因此,您应该只为每个连接详细信息创建一个全局/共享对象。

但是,您可以通过调用方法connect来强制连接,如下所示。虽然这种方法不是链接查询的推荐方法(应该使用任务),但它通常可以方便地检查连接。

我从自己的帖子中复制了示例:https ://github.com/vitaly-t/pg-promise/issues/81

下面是同时以两种方式执行此操作的示例,因此您可以选择您更喜欢的方法。

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 => {
        // Can check the server version here (pg-promise v10.1.0+):
        const serverVersion = obj.client.serverVersion;

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

输出:

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

库中的每个错误首先通过全局错误事件处理程序报告,然后才在相应的.catch处理程序中报告错误。

更新

测试连接的现代方法+一步获取服务器版本:

// tests connection and returns Postgres server version,
// if successful; or else rejects with connection error:
async function testConnection() {
    const c = await db.connect(); // try to connect
    c.done(); // success, release connection
    return c.client.serverVersion; // return server version
}

链接

于 2016-03-21T04:58:20.140 回答
-1

作为替代方案,在我升级 pg-promise 包之前,这些都不适合我

于 2021-02-28T23:41:35.377 回答