启动应用程序时使用pg-promise验证数据库连接

Ste*_* L. 25 postgresql node.js express pg-promise

我正在构建一个使用pg-promise模块连接到postgres数据库的快速应用程序.

我想确保启动应用程序服务器时数据库连接成功.换句话说,如果与数据库的连接失败,我想抛出一个错误.

我的server.js文件如下:

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}`);
});
Run Code Online (Sandbox Code Playgroud)

无论数据库连接是否有效,当前配置都将启动快速服务器,这不是我想要的行为.

我尝试浏览文档但找不到解决方案.我也试过了const db = pgp(databaseConfig).catch((err) => { // blow up });,但那不行,因为pgp没有回复承诺.

vit*_*y-t 48

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

当您实例化一个新的数据库对象时,如下所示:

const db = pgp(connection);
Run Code Online (Sandbox Code Playgroud)

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

从官方文档:

Object db表示数据库协议,具有惰性数据库连接,即只有实际的查询方法获取并释放连接.因此,您应该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);
    });
Run Code Online (Sandbox Code Playgroud)

输出:

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

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

替代

您可以简单地执行一种始终成功进行有效连接的查询,而不是手动建立连接,如下所示:

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

API链接:

  • @retorquere 当写这个答案时,还没有连接池这样的东西。目前发布的版本是5.9.5,仍然使用驱动程序v5.1,没有任何外部池可供共享,只有一个全局内部池。仅版本 6.x 使用最新的驱动程序及其连接池,可以通过 [db.$pool](http://vitaly-t.github.io/pg-promise/Database.html#.$pool) 访问。 (2认同)