作者:houjiajun | 来源:互联网 | 2024-12-19 12:55
在处理需要向数据库批量插入多条记录的场景时,使用pg-promise库可以显著提高效率和可靠性。假设您的表结构包含id(作为外键)、key和value字段,输入数据将以这些字段的数组形式提供。例如,您可能有如下数据结构:
const lst = [];
const obj1 = { id: 123, key: 'somekey', value: '1234' };
lst.push(obj1);
const obj2 = { id: 123, key: 'somekey1', value: '12345' };
lst.push(obj2);
如果您熟悉Microsoft SQL Server,可能会习惯于使用表值参数(TVP)来实现这一功能。但在PostgreSQL中,可以通过pg-promise库采用两种主要方法来完成相同的操作:事务处理和单一查询批量插入。
解决方案
1. 事务处理
通过事务处理可以确保所有记录要么全部成功插入,要么一个也不插入,从而保证数据的一致性。以下是使用pg-promise实现事务处理的具体代码:
db.tx(t => {
const queries = lst.map(l => {
return t.none('INSERT INTO your_table(id, key, value) VALUES(${id}, ${key}, ${value})', l);
});
return t.batch(queries);
})
.then(data => {
// 成功处理逻辑
// data 是由null组成的数组
})
.catch(error => {
// 错误处理逻辑
});
这段代码首先启动一个事务,然后为每个记录生成一个INSERT语句,并将这些语句作为一个批次执行。如果所有插入操作都成功,则事务提交;如果有任何一个失败,则整个事务回滚。
2. 单一查询批量插入
另一种方法是将所有待插入的值合并成一个单一的INSERT语句,这通常用于性能优化。具体实现方式可以参考pg-promise官方文档中的“性能提升”章节以及“多行插入”示例。
此外,如果希望自动生成ID并返回这些新生成的ID,可以通过修改上述代码实现:
db.tx(t => {
const queries = lst.map(l => {
return t.one('INSERT INTO your_table(key, value) VALUES(${key}, ${value}) RETURNING id',
l, a => +a.id);
});
return t.batch(queries);
})
.then(data => {
// 成功处理逻辑
// data 是新生成的ID数组
})
.catch(error => {
// 错误处理逻辑
});
这里的关键更改包括:不显式插入id字段,使用t.one方法代替t.none以获取每条插入记录的返回值,添加RETURNING id子句以返回新生成的ID,以及使用a => +a.id进行自动行转换。
对于需要高性能批量插入的场景,建议进一步阅读pg-promise的“多行插入”文档,以了解更详细的实现方法。