如何在 NodeJS/Express 服务器上使用 Postgres 池
How to use Postgres pooling on NodeJS/Express server
Postgres 的新概念和一般事务池的概念。在文档中,Postgres 建议对单个查询使用 pool.query 方法,并警告说“You must always return the client to the pool if you successfully check it out
”。我的意思是,您必须为客户端调用 client.release() 或为池调用 pool.end() (如果我错了请纠正我)。所以在我的 Node/Express 服务器上,我做了一个简单的测试:
const { Pool } = require('pg');
const pool = new Pool();
...
router.post('/test', async (req, res) => {
let { username } = req.body;
let dbRes;
try{
dbRes = await pool.query('SELECT * FROM users WHERE username = ', [username]);
} catch(err){
let errMsg = "Error fetching user data: " + err;
console.error(errMsg);
return res.send({"actionSuccess": false, "error": errMsg});
}
//do something with dbRes, maybe do an update query;
try{
await pool.end();
} catch(err){
return "There was an error ending database pool: " + err.stack;
}
res.send({"dbRes": dbRes.rows[0]})
});
我 运行 服务器,使用 Postman 对此 /test
路由进行 post 调用,一切正常。但是,如果我再次进行相同的调用,这次我会收到错误 Error: Cannot use a pool after calling end on the pool
。这是有道理的,我在这个请求中结束了池,但同时它没有意义。我猜 pools/clients 并没有像我最初认为的那样与单个服务器请求相关联,这意味着如果对节点服务器的一个请求结束了池,它也会结束所有其他请求的池(如果我'我错了!我只是在猜测)。如果是这样的话,那么我永远无法调用 pool.end(),因为只要节点服务器处于 运行ning 状态,我就想保留 tje 池 open/alive,用于其他服务器请求以及。这不禁让人质疑,我应该在哪里结束游泳池?让它永远打开可以吗?这是否与文档中所述的整个 You must always return the client to the pool if you successfully check it out
规则冲突?
如果您使用 await pool.query
语法,则无需担心将连接释放回池中。它为您处理关闭连接。在我看来,这是使用 pg 池的正确方法。您 can/should 删除了包含 pool.end()
代码片段的第二个 try/catch 块。
如果您使用旧学校 pool.connect
语法,则需要调用 done()
将连接释放回池中。即
pool.connect(function(err, client, done) {
var sql = "SELECT * FROM users WHERE username = ";
var values = [username];
client.query(sql, values, function(err, result) {
done(); // releases connection back to the pool
// Handle results
});
});
Postgres 的新概念和一般事务池的概念。在文档中,Postgres 建议对单个查询使用 pool.query 方法,并警告说“You must always return the client to the pool if you successfully check it out
”。我的意思是,您必须为客户端调用 client.release() 或为池调用 pool.end() (如果我错了请纠正我)。所以在我的 Node/Express 服务器上,我做了一个简单的测试:
const { Pool } = require('pg');
const pool = new Pool();
...
router.post('/test', async (req, res) => {
let { username } = req.body;
let dbRes;
try{
dbRes = await pool.query('SELECT * FROM users WHERE username = ', [username]);
} catch(err){
let errMsg = "Error fetching user data: " + err;
console.error(errMsg);
return res.send({"actionSuccess": false, "error": errMsg});
}
//do something with dbRes, maybe do an update query;
try{
await pool.end();
} catch(err){
return "There was an error ending database pool: " + err.stack;
}
res.send({"dbRes": dbRes.rows[0]})
});
我 运行 服务器,使用 Postman 对此 /test
路由进行 post 调用,一切正常。但是,如果我再次进行相同的调用,这次我会收到错误 Error: Cannot use a pool after calling end on the pool
。这是有道理的,我在这个请求中结束了池,但同时它没有意义。我猜 pools/clients 并没有像我最初认为的那样与单个服务器请求相关联,这意味着如果对节点服务器的一个请求结束了池,它也会结束所有其他请求的池(如果我'我错了!我只是在猜测)。如果是这样的话,那么我永远无法调用 pool.end(),因为只要节点服务器处于 运行ning 状态,我就想保留 tje 池 open/alive,用于其他服务器请求以及。这不禁让人质疑,我应该在哪里结束游泳池?让它永远打开可以吗?这是否与文档中所述的整个 You must always return the client to the pool if you successfully check it out
规则冲突?
如果您使用 await pool.query
语法,则无需担心将连接释放回池中。它为您处理关闭连接。在我看来,这是使用 pg 池的正确方法。您 can/should 删除了包含 pool.end()
代码片段的第二个 try/catch 块。
如果您使用旧学校 pool.connect
语法,则需要调用 done()
将连接释放回池中。即
pool.connect(function(err, client, done) {
var sql = "SELECT * FROM users WHERE username = ";
var values = [username];
client.query(sql, values, function(err, result) {
done(); // releases connection back to the pool
// Handle results
});
});