Node.js向PostgreSQL插入自定义类型及数组的问题求助
插入PostgreSQL自定义类型数组的解决方案
首先确认你的表字段类型是否为数组类型,如果原来的speeds字段是t_speed而非t_speed[],需要先修改表结构:
ALTER TABLE activities ALTER COLUMN speeds TYPE t_speed[];
下面提供两种在Node.js中插入t_speed[]类型数据的可行方法:
方法一:构造PostgreSQL原生数组格式
利用PostgreSQL的数组语法,将每个自定义类型元素转换为(date_value, speed_value)的record格式,再用ARRAY[]包裹成数组:
const { Client } = require('pg'); const client = new Client({ // 填入你的数据库连接配置:host, port, database, user, password }); async function insertWithNativeFormat() { await client.connect(); // 准备要插入的速度数据数组 const speedsData = [ { time: new Date('2024-02-06'), speed: 120 }, { time: new Date('2024-02-07'), speed: 135 }, { time: new Date('2024-02-08'), speed: 110 } ]; // 转换每个元素为PostgreSQL兼容的record字符串 const formattedRecords = speedsData.map(item => `('${item.time.toISOString().split('T')[0]}', ${item.speed})` ).join(','); const insertQuery = ` INSERT INTO activities (id_sportman, start_date, speeds) VALUES ($1, $2, ARRAY[${formattedRecords}]::t_speed[]) `; // 执行插入 await client.query(insertQuery, [1, new Date()]); await client.end(); } insertWithNativeFormat().catch(err => console.error(err));
方法二:利用JSON转换函数(更安全,避免SQL注入风险)
使用PostgreSQL的json_populate_recordset函数将JSON数组转换为自定义类型数组,这种方式不需要手动拼接字符串,安全性更高:
const { Client } = require('pg'); const client = new Client({ // 填入你的数据库连接配置 }); async function insertWithJsonConversion() { await client.connect(); const speedsData = [ { time: '2024-02-06', speed: 120 }, { time: '2024-02-07', speed: 135 }, { time: '2024-02-08', speed: 110 } ]; const insertQuery = ` INSERT INTO activities (id_sportman, start_date, speeds) VALUES ($1, $2, (SELECT array_agg(record) FROM json_populate_recordset(null::t_speed, $3) AS record)) `; // 将JSON数组作为参数传入,避免SQL注入 await client.query(insertQuery, [1, new Date(), JSON.stringify(speedsData)]); await client.end(); } insertWithJsonConversion().catch(err => console.error(err));
注意事项
- 确保
t_speed类型的time字段传入的是PostgreSQL支持的Date格式(YYYY-MM-DD),如果用Date对象,需要转换为对应格式的字符串。 - 方法二更推荐,因为它使用参数化查询,避免了手动拼接字符串带来的SQL注入风险。
内容的提问来源于stack exchange,提问作者itecko
相关产品推荐
相关产品推荐

