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

Posted

技术标签:

【中文标题】启动应用程序时使用 pg-promise 验证数据库连接【英文标题】:Verify database connection with pg-promise when starting an app 【发布时间】:2016-07-07 08:03:46 【问题描述】:

我正在构建一个使用 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`);
);

当前配置不管数据库连接是否有效都会启动express server,这不是我想要的行为。

我尝试浏览文档但找不到解决方案。我也试过了

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

但这不起作用,因为pgp 没有返回承诺。

【问题讨论】:

这里回答了:github.com/vitaly-t/pg-promise/issues/81 【参考方案1】:

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

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

const db = pgp(connection);

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

From the official documentation:

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

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

我从自己的帖子中复制了示例: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

库中的每个错误首先通过全局error 事件处理程序报告,然后才在相应的.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

链接

方法connect 事件error

【讨论】:

感谢@vitaly-t 的响应。这正是我想要的。 @retorquere 写这个答案时,没有连接池之类的东西。当前发布的版本是5.9.5,仍然使用驱动v5.1,没有任何外部池可以共享,它只有一个全局内部池。只有 6.x 版本使用最新的驱动程序及其连接池,可以通过db.$pool 访问。 @retorquere version 6.x of pg-promise has been released,您可以在其中通过db.$pool访问新的池对象;) @ManoharReddyPoreddy pg-promise 不做任何文件记录。 @ManoharReddyPoreddy 但是pg-monitor 是一个单独的库,超出了这个问题的范围。【参考方案2】:

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

【讨论】:

包更新与这些有什么关系?没有任何细节,这是一个完全没有价值的补充。

以上是关于启动应用程序时使用 pg-promise 验证数据库连接的主要内容,如果未能解决你的问题,请参考以下文章

Next.js API 路由与 pg-promise

是否可以使用 pg-promise 和 PostgreSQL(9.5)“创建数据库 ...”?

将 pg-promise 任务与 graphql 和 dataloader 一起使用

使用 pg-promise 插入多条记录

如何使用 pg-promise 帮助器返回插入查询结果值

使用 pg-promise 格式化 JSON 输出,将外键封装为对象