启动应用程序时使用 pg-promise 验证数据库连接 [英] Verify database connection with pg-promise when starting an app

查看:31
本文介绍了启动应用程序时使用 pg-promise 验证数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个使用 pg-promise 模块.

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

我的server.js文件如下:

const express = require("express");const 数据库配置 = {主机":本地主机",端口":5432,"数据库": "library_app",用户":postgres"};const pgp = require("pg-promise")({});const db = pgp(databaseConfig);const app = express();常量端口 = 5000;app.listen(port, (err) => {console.log(`在端口上运行服务器:${port}`);});

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

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

const db = pgp(databaseConfig).catch((err) => {//炸毁 });

但这没有用,因为 pgp 没有返回承诺.

解决方案

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

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

const db = pgp(connection);

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

来自官方文档:

<块引用>

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

但是,您可以通过调用方法connect,如图所示.虽然这种方法不是链接查询的推荐方式(任务应该用于那个),它通常可以方便地检查连接.

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

以下是同时以两种方式进行的示例,因此您可以选择更喜欢的方式.

const initOptions = {//全局事件通知;错误(错误,e){如果(e.cn){//与连接相关的错误;////使用散列后的密码报告连接,//用于安全错误日志记录,而不暴露密码.console.log('CN:', e.cn);console.log('EVENT:', error.message || error);}}};const pgp = require('pg-promise')(initOptions);//使用无效的连接字符串:const db = pgp('postgresql://userName:password@host:port/database');数据库连接().then(obj => {//可以在这里查看服务器版本(pg-promise v10.1.0+):const serverVersion = obj.client.serverVersion;obj.done();//成功,释放连接;}).catch(错误=> {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 处理程序中报告错误.

更新

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

//测试连接并返回 Postgres 服务器版本,//如果成功;否则拒绝连接错误:异步函数 testConnection() {const c = 等待 db.connect();//尝试连接c.完成();//成功,释放连接返回 c.client.serverVersion;//返回服务器版本}

链接

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.

解决方案

I am the author of pg-promise ;) And this isn't the first time this question is asked, so I'm giving it a detailed explanation here.

When you instantiate a new database object like this:

const db = pgp(connection);

...all it does - creates the object, but it does not try to connect. The library is built on top of the connection pool, and only the actual query methods request a connection from the pool.

From the official documentation:

Object db represents the database protocol, with lazy database connection, i.e. only the actual query methods acquire and release the connection. Therefore, you should create only one global/shared db object per connection details.

However, you can force a connection, by calling method connect, as shown further. And while this method is not a recommended way for chaining queries (Tasks should be used for that), it comes in handy checking for the connection in general.

I copied the example from my own post: https://github.com/vitaly-t/pg-promise/issues/81

Below is an example of doing it in two ways at the same time, so you can choose whichever approach you like better.

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

Outputs:

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

Every error in the library is first reported through the global error event handler, and only then the error is reported within the corresponding .catch handler.

Update

Modern approach to testing connection + getting server version in one step:

// 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
}

Links

这篇关于启动应用程序时使用 pg-promise 验证数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆