PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Inserções maciças com promessa de pg


ATUALIZAÇÃO

O melhor é ler o seguinte artigo:Importações de dados .

Como autor de pg-promise Fui compelido a finalmente fornecer a resposta certa para a pergunta, pois a publicada anteriormente não fazia justiça.

Para inserir um número enorme/infinito de registros, sua abordagem deve ser baseada no método sequência , que está disponível em tarefas e transações.
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
    });

Essa é a melhor abordagem para inserir um grande número de linhas no banco de dados, tanto do ponto de vista do desempenho quanto da limitação de carga.

Tudo o que você precisa fazer é implementar sua função getData de acordo com a lógica do seu aplicativo, ou seja, de onde vêm seus dados grandes, com base no index da sequência, para retornar cerca de 1.000 a 10.000 objetos por vez, dependendo do tamanho dos objetos e da disponibilidade dos dados.

Veja também alguns exemplos de API:

Pergunta relacionada:node-postgres com grande quantidade de consultas .

E nos casos em que você precisa adquirir os id-s gerados de todos os registros inseridos, você alteraria as duas linhas da seguinte forma:
// return t.none(insert);
return t.map(insert + 'RETURNING id', [], a => +a.id);

e
// db.tx(t => t.sequence(source))
db.tx(t => t.sequence(source, {track: true}))

apenas tome cuidado, pois manter muitos IDs de registro na memória pode criar uma sobrecarga.