UPDATE
最好的方法是阅读以下文章:数据导入 https://github.com/vitaly-t/pg-promise/wiki/Data-Imports.
作为作者pg-承诺 https://github.com/vitaly-t/pg-promise我被迫最终为这个问题提供正确的答案,因为之前发布的答案并没有真正做到公正。
为了插入大量/无限数量的记录,您的方法应该基于方法sequence http://vitaly-t.github.io/pg-promise/Task.html#sequence,这在任务和事务中可用。
var cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tableName'});
// returns a promise with the next array of data objects,
// while there is data, or an empty array when no more data left
function getData(index) {
if (/*still have data for the index*/) {
// - resolve with the next array of data
} else {
// - resolve with an empty array, if no more data left
// - reject, if something went wrong
}
}
function source(index) {
var t = this;
return getData(index)
.then(data => {
if (data.length) {
// while there is still data, insert the next bunch:
var insert = pgp.helpers.insert(data, cs);
return t.none(insert);
}
// returning nothing/undefined ends the sequence
});
}
db.tx(t => t.sequence(source))
.then(data => {
// success
})
.catch(error => {
// error
});
从性能角度和负载限制的角度来看,这是将大量行插入数据库的最佳方法。
您所要做的就是实现您的功能getData
根据您的应用程序的逻辑,即您的大数据来自哪里,基于index
序列的,一次返回大约 1,000 - 10,000 个对象,具体取决于对象的大小和数据可用性。
另请参阅一些 API 示例:
- spex -> 序列 http://vitaly-t.github.io/spex/global.html#sequence
- 链接和分离测序 http://vitaly-t.github.io/spex/tutorial-sequencing.html
- 流媒体和分页 http://vitaly-t.github.io/spex/tutorial-streaming.html
相关问题:具有大量查询的node-postgres https://stackoverflow.com/questions/29100807/node-postgres-with-massive-amount-of-queries.
如果您需要获取所有插入记录的生成 id,您可以按如下方式更改这两行:
// return t.none(insert);
return t.map(insert + 'RETURNING id', [], a => +a.id);
and
// db.tx(t => t.sequence(source))
db.tx(t => t.sequence(source, {track: true}))
请小心,因为在内存中保留太多记录 id 可能会造成过载。