【问题标题】:Async pg-node query execution on object's array对象数组上的异步 pg-node 查询执行
【发布时间】:2013-12-17 22:02:47
【问题描述】:

我有一个需要遍历的对象数组,并将每个项目插入数据库(postgres)。我正在使用_.each 来遍历数组。

arr = [ 
      {name: 'Aaron',    description: 'First'},
      {name: 'Brian',    description: 'Second'},
      {name: 'Chris',    description: 'Third'}
]

    var i = 0;
    _.each(array, function(lt){     
        var client = new pg.Client(self.getConnString());
        client.connect(function(err) {
            if (err) {
                          //doSomething//
            }
            var sql = 'insert into load_test (name,description) values(\''+lt.name+'\', \''+lt.description+'\')';
            console.log(i + " <- query: " + lt.name + " desc: " + lt.description);
            query = client.query(sql);
            query.on('end', client.end.bind(client));
            i++;
        });
    });//each

如何编写此函数 (_each),使其在每次查询执行时都是异步的?

谢谢

【问题讨论】:

  • 您为什么要这样做?会有什么好处?
  • 我将能够同步执行多次“插入”查询
  • 是的,但是为什么呢?为什么要为多个插入使用多个连接?你认为它会更快还是什么?
  • 哦,现在我得到了你的问题 :)... 我试图将客户端创建从每个范围中取出,但随后出现内存泄漏异常。

标签: postgresql asynchronous underscore.js node-postgres


【解决方案1】:

最后,解决方案如下:

self.InsertLT = function(index, callback){
        var client = new pg.Client(self.getConnString());
        if (index < arr.length){
            //console.log('index = ' + index);
            var sql = 'insert into table (name,description) values(\''+arr[index].name+'\', \''+arr[index].description+'\')';
            //console.log(sql);
            client.connect(function(err) {
                if (err) { 
                    logger.error(self.ERR_CONNECT_TO_DB + ' --> ' + err);
                    callback(-1);    
                }   
                client.query(sql, function(err, result){    
                    if (err){    
                        logger.error(self.ERR_RUNNING_QUERY + ' --> ' + err);    
                        callback(-1);    
                    }    
                    else{
                        client.end();
                        self.InsertLT(++index,callback);
                    }
                });//query
            });
        }
        else{
            callback();
        }

【讨论】:

  • 您正在为每个插入语句创建一个新连接。这太疯狂了。
  • 是的,但是您必须为每次插入设置和关闭连接
  • 所以?到数据库的无状态连接......我也可以通过使用连接池来实现它,然后我需要在连接回调中获得完成,然后只是使用它而不是调用 client.end()
【解决方案2】:

好的。我想我明白你现在的想法了。

我想说的是,你要进行三项更改。

  1. 在循环外创建连接(“客户端”)
  2. 使用参数化查询
  3. 将插入包装在事务中(这样它们都可以工作或一起失败)

我不做节点,但修改你的代码看起来像这样:

arr = [ 
      {name: 'Aaron',    description: 'First'},
      {name: 'Brian',    description: 'Second'},
      {name: 'Chris',    description: 'Third'}
];

var i = 0;
var client = new pg.Client(self.getConnString());
client.connect(function(err) {
    if (err) {
        //doSomething//
    }
    // I don't know how node does parameterised queries, but it will look
    // something like this
    var sql   = 'insert into load_test (name,description) values(?,?)';
    var query = client.query(sql);
    _.each(arr, function(lt) {
        console.log(i + " <- query: " + lt.name + " desc: " + lt.description);
        // There might be separate bind + excecute calls
        query.execute(lt.name, lt.description);
        i++;
    });
// There might be a client.disconnect() needed here

您需要查阅文档以了解正确的语法。

通常您会在应用程序启动时连接并保持数据库连接直到它退出。我猜你已经在某个地方的闭包中引用了对数据库连接的引用。如果您的查询需要“completed()”或“discard()”方法或类似方法,请确保您也调用它来释放资源。

【讨论】:

  • 首先感谢您的回答!在 pg-node 中,客户端查询就是查询的执行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多