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

如何检测CSV数据全部插入PostgreSQL完成(Node.js场景)

问题分析与修复方案

你的代码存在几个核心问题,导致无法正确等待所有插入完成并返回预期结果:

  1. 回调与async/await混用导致await失效:pool.connect()的回调版本并非Promise,await它不会等待回调内的逻辑执行完毕,testres函数会直接结束,自然返回undefined。
  2. forEach无法等待异步操作:csvData.forEach(async row => {})中的异步函数不会被forEach等待,循环会直接走完并执行done()释放连接,此时插入操作可能还未完成。
  3. 回调内的return不影响外层函数:你在client.query的回调里return 'finished !!!!!',这个return仅属于回调函数,和testres的返回值无关。
  4. countrec未初始化且依赖全局变量:这种统计方式容易出现竞态问题,导致计数不准确。

修复后的代码

import * as pg from 'pg';
const { Pool } = pg.default;
import { parse } from "fast-csv";
import { testres1 } from './createpdf.js';

const testres = async () => {
    const pool = new Pool({
        connectionString: conString,
        idleTimeoutMillis: 0,
        connectionTimeoutMillis: 0,
        ssl: {
            rejectUnauthorized: false,
        },
    });

    const query = "INSERT INTO _staging(firstName, lastName, Employee_ID, Employee_Unique_ID) \
                   VALUES($1, $2, $3, $4) RETURNING Employee_ID";
    
    // 使用Promise版本的connect获取客户端
    const client = await pool.connect();
    try {
        // 移除CSV表头行
        csvData.shift();
        // 生成所有插入操作的Promise数组
        const insertPromises = csvData.map(row => {
            return client.query(query, row)
                .catch(err => {
                    console.error(err.stack + "error row:", row);
                    throw err; // 抛出错误让Promise.all统一处理
                });
        });
        
        // 等待所有插入操作完成
        await Promise.all(insertPromises);
        
        // 所有插入完成后返回成功信息
        return 'finished !!!!!';
    } finally {
        // 确保无论成功失败都释放连接
        client.release();
    }
};

// 顶层执行逻辑(避免直接在模块顶层使用await的兼容性问题)
(async () => {
    try {
        const ddd = await testres();
        console.log('test :', ddd); // 此处会输出'finished !!!!!'
        const eee = await testres1();
    } catch (err) {
        console.error('操作失败:', err);
    }
})();

关键修复说明

  • 改用Promise版API:使用await pool.connect()获取客户端,这是pg库的原生Promise接口,能正确等待连接建立。
  • 用Promise.all批量等待异步操作:通过map生成所有插入操作的Promise数组,再用Promise.all()等待全部完成,确保所有记录插入后才继续执行后续逻辑。
  • 统一错误处理:在每个插入Promise中捕获错误并抛出,让Promise.all()能及时感知失败,最终在顶层try/catch中统一处理。
  • 安全释放连接:将连接释放放在finally块中,避免因错误导致连接泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:53:24