Вставка нескольких записей с помощью pg-prom

У меня есть сценарий, в котором мне нужно вставить несколько записей. У меня есть структура таблицы, такая как id (это fk из другой таблицы), key (char), value (char). Входом, который нужно сохранить, будет массив данных. пример: У меня есть некоторые объекты массива, например:

lst = [];

obj = {};
obj.id= 123;
obj.key = 'somekey';
obj.value = '1234';
lst.push(obj);

obj = {};
obj.id= 123;
obj.key = 'somekey1';
obj.value = '12345';
lst.push(obj);

Ответы

Ответ 1

Я являюсь автором pg-обещания.

Есть два способа вставить несколько записей. Первый и наиболее типичный способ - через транзакцию убедиться, что все записи вставлены правильно, или ни одной из них.

С pg-обещанием это делается следующим образом:

db.tx(t => {
    const queries = lst.map(l => {
        return t.none('INSERT INTO table(id, key, value) VALUES(${id}, ${key}, ${value})', l);
    });
    return t.batch(queries);
})
    .then(data => {
        // SUCCESS
        // data = array of null-s
    })
    .catch(error => {
        // ERROR
    });

Вы инициируете транзакцию с помощью метода tx, затем создаете все обещания запроса INSERT и затем разрешаете их все как пакет.

Второй подход заключается в объединении всех значений вставки в один запрос INSERT, который я подробно объясняю в Повышении производительности. Смотрите также: Многострочная вставка с pg-обещанием.

Дополнительные примеры см. в разделах Задачи и Транзакции.

Добавление

Стоит отметить, что в большинстве случаев мы не вставляем запись id, а генерируем ее автоматически. Иногда мы хотим вернуть новый идентификатор -s, а в других случаях нам все равно.

Приведенные выше примеры разрешаются с помощью массива null -s, поскольку batch разрешается с массивом отдельных результатов, а метод none разрешается с null в соответствии с его API..

Давайте предположим, что мы хотим сгенерировать новый идентификатор -s, и что мы хотим получить их все обратно. Для этого мы изменили бы код на следующий:

db.tx(t => {
    const queries = lst.map(l => {
        return t.one('INSERT INTO table(key, value) VALUES(${key}, ${value}) RETURNING id',
                       l, a => +a.id);
    });
    return t.batch(queries);
})
    .then(data => {
        // SUCCESS
        // data = array of new id-s;
    })
    .catch(error => {
        // ERROR
    });

т.е. изменения:

  • мы не вставляем значения id
  • мы заменим метод none на один, чтобы получить одну строку/объект из каждой вставки
  • мы добавляем RETURNING id к запросу, чтобы получить значение
  • мы добавляем a => +a.id для автоматического преобразования строк. См. также pg-обещание возвращает целые числа в виде строк, чтобы понять, для чего предназначен этот +.

UPDATE-1

Для высокопроизводительного подхода с помощью одного запроса INSERT см. Вставка в несколько строк с pg-обещанием.

ОБНОВЛЕНИЕ 2-

Обязательная статья: Импорт данных.