我试图通过接收来自客户端的请求来插入数百万条记录(大约6个字段/列),每次批量插入尝试使用10,000条记录(使用sequelize
。js和bulkCreate()
)
这显然是个坏主意,所以我试着调查node-pg-copy-streams
但是,我不想在客户端发起更改,其中json数组是这样发送的
# python
data = [
{
"column a":"a values",
"column b":"b values",
},
...
# 10,000 items
...
]
request.post(data=json.dumps(data), url=url)
在nodejs的服务器端,我如何在以下骨架中流式传输收到的request.body
?
.post(function(req, res){
// old sequelize code
/* table5.bulkCreate(
req.body, {raw:true}
).then(function(){
return table5.findAll();
}).then(function(result){
res.json(result.count);
});*/
// new pg-copy-streams code
pg.connect(function(err, client, done) {
var stream = client.query(copyFrom('COPY my_table FROM STDIN'));
// My question is here, how would I stream or pipe the request body ?
// ?.on('error', done);
// ?.pipe(stream).on('finish', done).on('error', done);
});
});
答案 0 :(得分:2)
这是我如何解决我的问题,
首先将我的req.body dict转换为TSV的函数(不是初始问题的一部分)
each
其余的原始.post功能
/**
* Converts a dictionary and set of keys to a Tab Separated Value blob of text
* @param {Dictionary object} dict
* @param {Array of Keys} keys
* @return {Concatenated Tab Separated Values} String
*/
function convertDictsToTSV(dicts, keys){
// ...
}
答案 1 :(得分:0)
从技术上讲,这里没有流媒体,不是NodeJS流的工作方式。
每次发送一大块10,000条记录,并希望服务器端插入这些记录并向客户端返回OK以发送另外10,000条记录。那是限制/分页数据,而不是流媒体。
一旦您的服务器收到了接下来的10,000条记录,请插入它们(通常作为一个事务),然后用OK回复客户端,以便它可以发送下一条10,000条记录。
使用node-postgres编写事务并不是一件容易的事,因为它太低级了。
以下是在pg-promise的帮助下如何执行此操作的示例:
function insertRecords(records) {
return db.tx(t=> {
var inserts = [];
records.forEach(r=> {
var query = t.none("INSERT INTO table(fieldA, ...) VALUES(${propA}, ...)", r);
inserts.push(query);
});
return t.batch(inserts);
});
}
然后在你的HTTP处理程序中,你会写:
function myPostHandler(req, res) {
// var records = get records from the request;
insertRecords(records)
.then(data=> {
// set response as success;
})
.catch(error=> {
// set response as error;
});
}