sql >> Base de Datos >  >> RDS >> PostgreSQL

Inserciones masivas con pg-promise

ACTUALIZAR

Lo mejor es leer el siguiente artículo:Importaciones de datos .

Como autor de pg-promise Me vi obligado a dar finalmente la respuesta correcta a la pregunta, ya que la publicada anteriormente no le hacía justicia.

Para insertar una cantidad masiva/infinita de registros, su enfoque debe basarse en el método secuencia , que está disponible en tareas y transacciones.

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
    });

Este es el mejor enfoque para insertar una gran cantidad de filas en la base de datos, tanto desde el punto de vista del rendimiento como de la aceleración de la carga.

Todo lo que tienes que hacer es implementar tu función getData de acuerdo con la lógica de su aplicación, es decir, de dónde provienen sus grandes datos, según el index de la secuencia, para devolver entre 1000 y 10 000 objetos a la vez, según el tamaño de los objetos y la disponibilidad de datos.

Vea también algunos ejemplos de API:

Pregunta relacionada:node-postgres con una gran cantidad de consultas .

Y en los casos en los que necesite adquirir identificadores generados de todos los registros insertados, cambiaría las dos líneas de la siguiente manera:

// return t.none(insert);
return t.map(insert + 'RETURNING id', [], a => +a.id);

y

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

solo tenga cuidado, ya que mantener demasiadas identificaciones de registro en la memoria puede crear una sobrecarga.