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

Node.js Lambda中pg setTypeParser处理PostgreSQL日期失效排查

问题描述

本地Node.js环境中,这段代码能正常去除PostgreSQL日期类型的时间戳部分:

const { Client } = require('pg');
const pg = require('pg');
pg.types.setTypeParser(1082, value => value);

// 连接信息
const connectionString = 'postgresql://postgres:password@localhost:5432/postgres';

// 创建客户端实例
const client = new Client({
  connectionString: connectionString
});

// 连接PostgreSQL服务器
client.connect()
.then(() => {
  console.log('Connected to the database');
  // 示例查询
  client.query('SELECT * FROM test.testy', (err, res) => {
    if (err) {
      console.error('Error executing query', err);
    } else {
      console.log('Query result:', res.rows);
    }
  });

})
.catch(err => {
  console.error('Error connecting to the database', err);
});

但把pg.types.setTypeParser(1082, function(stringValue) {return stringValue;})(1082对应PostgreSQL日期类型)加到Node.js Lambda函数后,日期字段仍带时间戳,比如date_of_birth: 1991-02-28T00:00:00.000Z,我想要的是纯日期1991-02-28。Lambda代码如下:

const pg = require('pg');

pg.types.setTypeParser(1082, function(stringValue) {
  return stringValue;  //1082 for date type
});

async function query (q, secret, values = []) {
const pool = new pg.Pool({
  user: secret.username,
  host: secret.host,
  database: secret.dbname,
  password: secret.password,
  port: secret.port,
});

if (typeof q === 'string' || q instanceof String) {
  q = [q];
}

const client = await pool.connect();
let res;
try {
    await client.query('BEGIN');
    try {
        for (let i = 0; i < q.length; i++) {
          const qstring = q[i];
          if (values === []) {
            res = await client.query(qstring);
          }
          else {
            res = await client.query(qstring, values[i]);
          }
        }
        await client.query('COMMIT');
    } catch (err) {
        await client.query('ROLLBACK');
        throw err;
    }
} finally {
    client.release();
}
return res;
};

exports.query = query;

作为Node.js新手,我哪里操作错了?

解决办法

核心问题要么是Lambda里pg的类型解析器没生效,要么是结果返回时被JSON序列化自动加了时间戳,以下是具体修复步骤:

1. 确保类型解析器完全生效

虽然你已经把解析器写在Pool初始化前,但可以尝试先清除默认解析器再设置,避免被内置逻辑覆盖:

const pg = require('pg');
const types = pg.types;
// 先清空默认解析器,再设置自定义的
types.setTypeParser(1082, null);
types.setTypeParser(1082, (value) => value);

2. 手动处理返回结果的日期字段

Lambda会自动把返回的对象序列化为JSON,如果日期字段是Date对象,JSON.stringify会自动转成带时间戳的格式。可以在返回前手动处理:

// 在return res之前添加这段代码,处理rows里的日期字段
if (res?.rows) {
  res.rows.forEach(row => {
    // 以date_of_birth为例,其他日期字段同理
    if (row.date_of_birth) {
      if (row.date_of_birth instanceof Date) {
        // 转成纯日期字符串
        row.date_of_birth = row.date_of_birth.toISOString().split('T')[0];
      } else if (typeof row.date_of_birth === 'string' && row.date_of_birth.includes('T')) {
        // 如果已经是带时间戳的字符串,直接截取前10位
        row.date_of_birth = row.date_of_birth.split('T')[0];
      }
    }
  });
}

3. 对齐本地和Lambda的pg版本

本地和Lambda的pg版本可能不一样,不同版本的类型解析逻辑有差异。在package.json里固定版本:

"dependencies": {
  "pg": "^8.11.3" // 替换成你本地测试通过的版本
}

4. 检查Pool配置是否有干扰

避免使用会自动转换日期的Pool配置项,比如parseInputDatesAsUTC,确保配置里没有这类可能影响解析的参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:35:22