PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Многоредова вложка с pg-promise

Аз съм авторът на pg-promise.

В по-старите версии на библиотеката това беше обхванато от опростени примери в статията Performance Boost, която все още е добро четиво при писане на високопроизводителни приложения за бази данни.

По-новият подход е да се разчита на пространството от имена на помощниците, което в крайна сметка е гъвкаво и оптимизирано за производителност.

const pgp = require('pg-promise')({
    /* initialization options */
    capSQL: true // capitalize all generated SQL
});
const db = pgp(/*connection*/);
    
// our set of columns, to be created only once (statically), and then reused,
// to let it cache up its formatting templates for high performance:
const cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tmp'});
    
// data input values:
const values = [{col_a: 'a1', col_b: 'b1'}, {col_a: 'a2', col_b: 'b2'}];
    
// generating a multi-row insert query:
const query = pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')
    
// executing the query:
await db.none(query);

Вижте API:ColumnSet, вмъкване.

Такова вмъкване дори не изисква транзакция, защото ако един набор от стойности не успее да се вмъкне, нито една няма да се вмъкне.

И можете да използвате същия подход, за да генерирате някоя от следните заявки:

  • едноредов INSERT
  • многоредов INSERT
  • единредов UPDATE
  • многоредов UPDATE

Защитени ли са вмъкванията, използващи нотация ${}, срещу sql инжекция?

Да, но не сам. Ако вмъквате имена на схеми/таблици/колони динамично, важно е да използвате SQL имена, които в комбинация ще защитят кода ви от SQL инжектиране.

Свързан въпрос:Многоредови актуализации на PostgreSQL в Node.js

екстри

В:Как да получа id на всеки нов запис по едно и също време?

А: Просто като добавите RETURNING id към вашата заявка и изпълнението й с метод много:

const query = pgp.helpers.insert(values, cs) + ' RETURNING id';
    
const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]

или дори по-добре, вземете идентификаторите и преобразувайте резултата в масив от цели числа, като използвате карта на метода:

const res = await db.map(query, undefined, a => +a.id);
//=> [1, 2, ...]

За да разберем защо използвахме + там вижте:pg-promise връща цели числа като низове.

АКТУАЛИЗИРАНЕ-1

За вмъкване на огромен брой записи вижте Импортиране на данни.

АКТУАЛИЗИРАНЕ-2

Използвайки v8.2.1 и по-нова версия, можете да обвиете статичното генериране на заявка във функция, така че да може да бъде генерирано в метода на заявката, за да отхвърлите, когато генерирането на заявка не успее:

// generating a multi-row insert query inside a function:
const query = () => pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')
    
// executing the query as a function that generates the query:
await db.none(query);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да декларирам локални променливи в postgresql?

  2. Определяне на OID на таблица в Postgres 9.1?

  3. как да поставим префикс на низ преди последователност, генерирана от postgresql?

  4. PostgreSQL:текущ брой редове за заявка „по минута“

  5. Spring Data JPA одитът не работи за метода за актуализиране на JpaRepository с анотация @Modifying, защо?