将PostgreSQL连接池导入其他文件执行查询时出现语法错误
解决PostgreSQL连接池跨文件调用时的语法错误问题
问题背景
在postgre.js中创建PostgreSQL连接池并导出后,内部的testConnect和testSmallQuery函数执行正常,能返回0行数据;但将连接池导入user.js的getUserById函数中执行完全相同的查询时,抛出「error: syntax error at end of input」错误。
相关代码
postgre.js
const config = require("../config/config"); const { Pool, Client } = require("pg") const pool = new Pool({ host : config.HOST, port : config.PORT, // default port for mysql is 3306 user : config.USER, password : config.PASSWORD, database : config.DB, idleTimeoutMillis: 30000 }); pool.on('error', function (err, client) { console.error('idle client error', err.message, err.stack); }); async function testConnect() { console.log('Before connect'); const client = await pool.connect(); console.log('Database Connected!'); // client.release(); } async function testSmallQuery() { console.log('Before small query'); const sql = "SELECT * FROM users"; const result = await pool.query(sql); console.log('Small query returned %s rows', result.rows.length); // pool.end(); } async function connect() { await testConnect(); await testSmallQuery(); } connect(); module.exports = pool;
user.js
const pool = require("./postgres") async getUserById(req, res, next) { try { const sql = "SELECT * FROM users"; const result = await pool.query(sql); pool.end(); return res.status(200).json(result.rows); } catch (error) { console.log(error); } }
错误信息
错误截图显示报错内容为:error: syntax error at end of input,伴随调用栈信息。
问题根源
报错的核心原因是**user.js中调用了pool.end()**:这个方法会直接关闭整个连接池,释放所有底层连接资源。第一次请求执行时连接池被关闭,后续请求再调用pool.query()时,连接池无法正常提供可用连接,导致查询执行异常,错误信息表现为语法错误(实际是连接池已关闭后的异常反馈)。
另外,postgre.js中模块加载时自动执行connect()的逻辑虽不直接导致报错,但属于非必要的提前连接,可优化。
修复方案
1. 移除user.js中的pool.end()调用
连接池的设计目标是复用连接,pool.query()内部会自动从池中获取连接,执行完成后将连接释放回池,无需手动关闭整个连接池。
修改后的user.js:
const pool = require("./postgres") async function getUserById(req, res, next) { try { const sql = "SELECT * FROM users"; const result = await pool.query(sql); return res.status(200).json(result.rows); } catch (error) { console.log(error); next(error); // 建议将错误传递给全局错误处理中间件 } }
2. 可选优化:移除postgre.js中的自动连接逻辑
模块加载时自动执行connect()会提前建立连接,改为按需调用测试逻辑更符合最佳实践:
修改后的postgre.js:
const config = require("../config/config"); const { Pool } = require("pg") const pool = new Pool({ host : config.HOST, port : config.PORT, user : config.USER, password : config.PASSWORD, database : config.DB, idleTimeoutMillis: 30000 }); pool.on('error', function (err, client) { console.error('idle client error', err.message, err.stack); }); // 测试函数改为按需调用,避免模块加载时自动执行 async function testConnect() { console.log('Before connect'); const client = await pool.connect(); console.log('Database Connected!'); client.release(); // 记得释放连接 } async function testSmallQuery() { console.log('Before small query'); const sql = "SELECT * FROM users"; const result = await pool.query(sql); console.log('Small query returned %s rows', result.rows.length); } // 如需测试,手动调用connect() // async function connect() { // await testConnect(); // await testSmallQuery(); // } // connect(); module.exports = pool;
额外说明
如果需要在应用退出时关闭连接池,可在应用的退出钩子中调用pool.end(),示例:
// 在应用入口文件中添加 process.on('SIGINT', async () => { await pool.end(); process.exit(0); });
内容的提问来源于stack exchange,提问作者Javed Saifi
相关产品推荐
相关产品推荐

