node.js, pg, postgresql и запросы вставки (приложение зависает)

У меня есть следующее простое приложение узла для вставки данных в базу данных postgres:

var pg = require('pg');
var dbUrl = 'tcp://user:psw@localhost:5432/test-db';

pg.connect(dbUrl, function(err, client, done) {
    for (var i = 0; i < 1000; i++) {
        client.query(
            'INSERT into post1 (title, body, created_at) VALUES($1, $2, $3) RETURNING id', 
            ['title', 'long... body...', new Date()], 
            function(err, result) {
                if (err) {
                    console.log(err);
                } else {
                    console.log('row inserted with id: ' + result.rows[0].id);
                }

            });
    }
});

После запуска node app.js в терминале он вставляет 1000 строк в базу данных, затем приложение зависает и не завершается. Что я делаю не так? Я просмотрел примеры модулей pg, но не заметил, что делаю что-то по-другому ...


person Darius Kucinskas    schedule 26.06.2013    source источник
comment
Приложение зависает из-за того, что цикл for выполняется как синхронный код. Пока выполняется итерация цикла, исполняемый файл узла не может отвечать на другие запросы. Кроме того, вызовы client.query являются синхронными, так как цикл for запускает этот запрос, вы будете захлопывать данные всеми этими запросами.   -  person BrandonKowalski    schedule 26.06.2013


Ответы (1)


Я пропустил звонок client.end (); Теперь приложение закрывается правильно:

pg.connect(dbUrl, function(err, client, done) {
    var i = 0, count = 0; 
    for (i = 0; i < 1000; i++) {
        client.query(
            'INSERT into post1 (title, body, created_at) VALUES($1, $2, $3) RETURNING id', 
            ['title', 'long... body...', new Date()], 
            function(err, result) {
                if (err) {
                    console.log(err);
                } else {
                    console.log('row inserted with id: ' + result.rows[0].id);
                }

                count++;
                console.log('count = ' + count);
                if (count == 1000) {
                    console.log('Client will end now!!!');
                    client.end();
                }
            });        
    }
});
person Darius Kucinskas    schedule 27.06.2013
comment
Другой способ - использовать client.on ('слив', client.end.bind (client)); - person Darius Kucinskas; 27.06.2013
comment
А что, если запрос PG завершится неудачно для i = 207? Как ты с этим справишься? Лучше всего использовать одну вставку со многими значениями? То есть вы позволяете циклу for построить запрос и добавляете надлежащее экранирование / проверку ваших данных. - person FORTRAN; 03.10.2014