You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署后NodeJS中MySQL查询返回空对象问题排查

问题原因及解决方法

核心问题分析

1. 异步函数未正确处理

getAll是异步函数,调用时未用await或.then()处理Promise,导致路由直接返回Promise对象给客户端,Express会将其序列化为空对象。同时try/catch无法捕获异步函数的错误,因为错误被包裹在Promise中。

2. 查询方法Promise化错误

connection.query.bind(connection)仅绑定了this上下文,返回的仍是基于回调的函数,并非Promise。直接await该函数不会等待查询完成,rows无法获取正确的查询结果。

3. 结果处理逻辑缺陷

  • result未初始化,若查询结果为空或遍历逻辑错误,最终返回undefined,Express会将undefined转为空对象响应。
  • 遍历Object.keys(rows)并覆盖result的逻辑错误:mysql模块查询结果默认是数组,遍历索引后result只会保留最后一条数据,而非全部结果。

4. 连接未释放(隐藏隐患)

查询完成后未释放连接回池,长期运行会导致连接池耗尽,引发新问题。

修复步骤

修复路由函数

将路由改为异步函数,使用await等待查询结果,并正确捕获错误:

router.get('/product-page', async (req, res) => {
    try {
        const data = await getAll(req);
        res.send(data);
    } catch (error) {
        logger.customLogger.log('debug', 'route error', error);
        res.status(500).send({ error: '查询失败' });
    }
});

修复查询函数

正确Promise化查询方法,简化结果处理,并释放连接:

async function getAll(req) {
    const connection = await util.promisify(pool.getConnection.bind(pool))();
    console.log(`connected as id ${connection.threadId}`);
    logger.customLogger.log('debug', 'await-connection', 'connection');
    
    // 正确包装查询方法为Promise
    const query = util.promisify(connection.query).bind(connection);
    const rows = await query('SELECT * FROM cam_features');
    
    logger.customLogger.log('debug', 'result:', rows);
    // 直接返回查询结果(mysql默认返回数组,包含所有行)
    const result = rows;
    
    // 释放连接回池
    connection.release();
    return result;
}

Docker环境额外检查

  • 确认Docker Compose中数据库服务名称为sql,应用容器与数据库容器处于同一网络,能正常解析该主机名。
  • 验证paragon数据库中cam_features表存在且有数据,避免初始化脚本未正确执行。
  • 确认数据库用户root拥有paragon数据库的查询权限。

内容的提问来源于stack exchange,提问作者Yenmangu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:15:38