nodeJS вставляет данные в ошибку PostgreSQL

У меня странная ошибка при использовании NodeJS с PostgreSQL, и я надеюсь, что вы можете мне помочь.

У меня есть огромное количество наборов данных, около 2 миллионов записей, которые я хочу вставить в свою БД.

Одна информация состоит из 4 столбцов:

id: string,
points: float[][]
mid: float[]
occurences: json[]

Я вставляю данные так:

let pgp = require('pg-promise')(options);
let connectionString = 'postgres://archiv:archiv@localhost:5432/fotoarchivDB';
let db = pgp(connectionString);

cityNet.forEach((arr) => {
    db
    .none(
        "INSERT INTO currentcitynet(id,points,mid,occurences) VALUES $1",
        Inserts("${id},${points}::double precision[],${mid}::double precision[],${occurences}::json[]",arr))
    .then(data => {
        //success
    })
    .catch(error => {
        console.log(error);
        //error
    });
})

function Inserts(template, data) {
    if (!(this instanceof Inserts)) {
        return new Inserts(template, data);
    }
    this._rawDBType = true;
    this.formatDBType = function() {
    return data.map(d => "(" + pgp.as.format(template, d) + ")").join(",");
};

Это работает точно для первых 309248 фрагментов данных, а затем внезапно выдает ошибку со следующим (как это выглядит) для каждой следующей информации, которую он пытается вставить:

{ error: syntax error at end of input
at Connection.parseE (/home/christian/Masterarbeit_reworked/projekt/server/node_modules/pg-promise/node_modules/pg/lib/connection.js:539:11)
at Connection.parseMessage (/home/christian/Masterarbeit_reworked/projekt/server/node_modules/pg-promise/node_modules/pg/lib/connection.js:366:17)
at Socket.<anonymous> (/home/christian/Masterarbeit_reworked/projekt/server/node_modules/pg-promise/node_modules/pg/lib/connection.js:105:22)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:548:20)
name: 'error',
length: 88,
severity: 'ERROR',
code: '42601',
detail: undefined,
hint: undefined,
position: '326824',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'scan.l',
line: '1074',
routine: 'scanner_yyerror' }

Запись 'position' изменяется для каждого повторяющегося сообщения об ошибке.

Я могу повторить это, и это всегда будет ошибка после 309248 записей. Когда я пытаюсь вставить меньше, например 1000 записей, ошибка не возникает.

Это действительно смущает меня. Я думал, что PostgreSQL не имеет максимального количества строк. Также сообщение об ошибке мне не помогает вообще.

Решено Ошибка найдена. В моих данных были "нулевые" записи, которые проскользнули в него. Сработала фильтрация нулевых данных. Я опробую другие рекомендации для вставки данных, так как текущий способ работает, но производительность очень дрянная.

2 ответа

Решение

Я не уверен, но похоже, что вы неправильно указали структуру данных в последнем элементе (309249) и PostgreSQL не может проанализировать какое-либо свойство

Я автор pg-обещания. Весь ваш подход должен быть изменен на следующий.

Правильный способ сделать массивные вставки через pg-обещание:

const pgp = require('pg-promise')({
    capSQL: true
});

const db = pgp(/*connection details*/);

var cs = new pgp.helpers.ColumnSet([
    'id',
    {name: 'points', cast: 'double precision[]'},
    {name: 'mid', cast: 'double precision[]'},
    {name: 'occurences', cast: 'json[]'}
], {table: 'currentcitynet'});

function getNextInsertBatch(index) {
    // retrieves the next data batch, according to the index, and returns it
    // as an array of objects. A normal batch size: 1000 - 10,000 objects,
    // depending on the size of the objects.
    //
    // returns null when there is no more data left.
}

db.tx('massive-insert', t => {
    return t.sequence(index => {
        const data = getNextInsertBatch(index);
        if (data) {
            const inserts = pgp.helpers.insert(data, cs);
            return t.none(inserts);
        }
    });
})
    .then(data => {
        console.log('Total batches:', data.total, ', Duration:', data.duration);
    })
    .catch(error => {
        console.log(error);
    });

ОБНОВИТЬ

И если getNextInsertBatch может только получить данные асинхронно, затем вернуть обещание и обновить sequence->source Обратный звонок соответственно:

return t.sequence(index => {
    return getNextInsertBatch(index)
        .then(data => {
            if (data) {
                const inserts = pgp.helpers.insert(data, cs);
                return t.none(inserts);
            }
        });
});

Ссылки по теме:

Другие вопросы по тегам