PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Massive Einsätze mit PG-Versprechen

AKTUALISIEREN

Lesen Sie dazu am besten folgenden Artikel:Datenimporte .

Als Autor von pg-promise Ich war gezwungen, endlich die richtige Antwort auf die Frage zu geben, da die zuvor veröffentlichte ihr nicht wirklich gerecht wurde.

Um eine große/unendliche Anzahl von Datensätzen einzufügen, sollte Ihr Ansatz auf der Methode Sequenz , das innerhalb von Aufgaben und Transaktionen verfügbar ist.

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

Dies ist der beste Ansatz, um eine große Anzahl von Zeilen in die Datenbank einzufügen, sowohl im Hinblick auf die Leistung als auch auf die Lastdrosselung.

Alles, was Sie tun müssen, ist Ihre Funktion getData zu implementieren nach der Logik Ihrer App, d.h. woher Ihre großen Daten kommen, basierend auf dem index der Sequenz, um etwa 1.000 bis 10.000 Objekte gleichzeitig zurückzugeben, je nach Größe der Objekte und Datenverfügbarkeit.

Siehe auch einige API-Beispiele:

Verwandte Frage:node-postgres mit massiver Menge an Abfragen .

Und in Fällen, in denen Sie generierte IDs aller eingefügten Datensätze abrufen müssen, würden Sie die beiden Zeilen wie folgt ändern:

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

und

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

Seien Sie jedoch vorsichtig, da zu viele Datensatz-IDs im Speicher zu einer Überlastung führen können.