用brianc / node-postgres批量插入到Postgres中

我在nodejs中有下面的代码使用pg( https://github.com/brianc/node-postgres )我的代码为员工创build订阅是这样的。

client.query( 'INSERT INTO subscriptions (subscription_guid, employer_guid, employee_guid) values ($1,$2,$3)', [ datasetArr[0].subscription_guid, datasetArr[0].employer_guid, datasetArr[0].employee_guid ], function(err, result) { done(); if (err) { set_response(500, err, res); logger.error('error running query', err); return console.error('error running query', err); } logger.info('subscription with created'); set_response(201); }); 

正如你已经注意到datasetArr是一个数组。 我想一次为多个员工创build批量订阅。 但是我不想循环访问数组。 有没有办法做到这一点与pg的框?

我做了一个相同的问题,但没有find解决scheme。 使用asynchronous库很容易多次使用查询,并执行必要的error handling。

可能是这个代码变种的帮助。 (用于插入10.000个小json对象到一个空的数据库需要6秒)。

克里斯托夫

 function insertData(item,callback) { client.query('INSERT INTO subscriptions (subscription_guid, employer_guid, employee_guid) values ($1,$2,$3)', [ item.subscription_guid, item.employer_guid, item.employee_guid ], function(err,result) { // return any err to async.each iterator callback(err); }) } async.each(datasetArr,insertData,function(err) { // Release the client to the pg module done(); if (err) { set_response(500, err, res); logger.error('error running query', err); return console.error('error running query', err); } logger.info('subscription with created'); set_response(201); }) 

它寻找我最好的方法是使用PostgreSQL json函数:

 client.query('INSERT INTO table (columns) ' + 'SELECT m.* FROM json_populate_recordset(null::your_custom_type, $1) AS m', [JSON.stringify(your_json_object_array)], function(err, result) { if(err) { console.log(err); } else { console.log(result); } }); 

要从NodeJS批量插入到Postgresql中,更好的select是使用由Postgres和pg-copy-streams提供的“COPY”命令。

代码片段: https : //gist.github.com/sairamkrish/477d20980611202f46a2d44648f7b14b

 /* Pseudo code - to serve as a help guide. */ const copyFrom = require('pg-copy-streams').from; const Readable = require('stream').Readable; const { Pool,Client } = require('pg'); const fs = require('fs'); const path = require('path'); const datasourcesConfigFilePath = path.join(__dirname,'..','..','server','datasources.json'); const datasources = JSON.parse(fs.readFileSync(datasourcesConfigFilePath, 'utf8')); const pool = new Pool({ user: datasources.PG.user, host: datasources.PG.host, database: datasources.PG.database, password: datasources.PG.password, port: datasources.PG.port, }); export const bulkInsert = (employees) => { pool.connect().then(client=>{ let done = () => { client.release(); } var stream = client.query(copyFrom('COPY employee (name,age,salary) FROM STDIN')); var rs = new Readable; let currentIndex = 0; rs._read = function () { if (currentIndex === employees.length) { rs.push(null); } else { let employee = employees[currentIndex]; rs.push(employee.name + '\t' + employee.age + '\t' + employee.salary + '\n'); currentIndex = currentIndex+1; } }; let onError = strErr => { console.error('Something went wrong:', strErr); done(); }; rs.on('error', onError); stream.on('error', onError); stream.on('end',done); rs.pipe(stream); }); } 

在此链接中解释更详细的细节

创build你的数据结构为:

 [ [val1,val2],[val1,val2] ...] 

然后将其转换为一个string:

  JSON.stringify([['a','b'],['c']]).replace(/\[/g,"(").replace(/\]/g,")").replace(/"/g,'\'').slice(1,-1) 

追加到查询,你就完成了!

同意它有stringparsing成本,但其方式比单插入便宜。

使用ORM; 例如: 异议 。

此外,根据您的数据库服务器和活动连接数量增加连接池大小。

 someMovie .$relatedQuery('actors') .insert([ {firstName: 'Jennifer', lastName: 'Lawrence'}, {firstName: 'Bradley', lastName: 'Cooper'} ]) .then(function (actors) { console.log(actors[0].firstName); console.log(actors[1].firstName); });