启动应用程序时使用 pg-promise 验证数据库连接 [英] Verify database connection with pg-promise when starting an app
问题描述
我正在构建一个使用 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/shareddb
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屋!