sql >> Databasteknik >  >> RDS >> PostgreSQL

Massiva skär med pg-löfte

UPPDATERA

Bäst är att läsa följande artikel:Dataimport .

Som författare till pg-promise Jag var tvungen att äntligen ge det rätta svaret på frågan, eftersom den som publicerades tidigare inte riktigt gjorde den rättvisa.

För att kunna infoga ett enormt/oändligt antal poster bör ditt tillvägagångssätt baseras på metoden sekvens , som är tillgängligt inom uppgifter och transaktioner.

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

Detta är det bästa sättet att infoga ett enormt antal rader i databasen, både ur prestandasynpunkt och belastningsbegränsning.

Allt du behöver göra är att implementera din funktion getData enligt logiken i din app, det vill säga var din stora data kommer ifrån, baserat på index av sekvensen, för att returnera cirka 1 000 - 10 000 objekt åt gången, beroende på objektens storlek och datatillgänglighet.

Se även några API-exempel:

Relaterad fråga:node-postgres med enorma mängder frågor .

Och i de fall där du behöver skaffa genererade ID:n för alla infogade poster, skulle du ändra de två raderna enligt följande:

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

och

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

var bara försiktig, eftersom för många post-ID:n i minnet kan skapa en överbelastning.



  1. Skillnaden mellan NullIf() och IfNull() i SQLite

  2. Det går inte att visa BLOB-bild med data-URI

  3. SCD typ 3

  4. Oracle SQL konverterar datumformat från DD-mån-ÅÅ till ÅÅÅÅMM