Использование опции «пропустить» в многострочном обновлении

Я новичок в NodeJs и пытался использовать pg-promise для выполнения всех запросов к моя база данных PG. Я хочу иметь возможность динамически обновлять столбцы, то есть иногда я буду обновлять только два столбца для строки, иногда я буду обновлять их все и т. д. Мой ввод будет JSON.

Поскольку я хочу, чтобы конечная точка могла обновлять несколько строк, я попытался использовать пространство имен помощников с Набор столбцов.

Вот мой код Javascript (вдохновленный предыдущими ответами stackoverflow):

  /* logic for skipping columns: */
  const skip = c => !c.exists || c.value === undefined;
  
  /* all the columns of the table */
  const column_structure = new dbconfig.pgp.helpers.ColumnSet(
  [ '?id',
    {name: 'firstname', skip}, 
    {name: 'surname', skip}, 
    {name: 'yob', skip}, // year of birth
    {name: 'defensive_skill', skip}, 
    {name: 'offensive_skill', skip}, 
    {name: 'login', skip}, 
    {name: 'password', skip}
  ],
     {table: 'players'});

Вот JSON, который я передаю в конечную точку:

[{
  "id" : 25,
  "firstname": "Stephen",
  "surname": "Harrison",
  "yob": 1991,
  "defensive_skill": 5,
  "offensive_skill": 3,
  "login": "harry",
  "password": "123456"
},
{
  "id": 26,
  "firstname": "Chris",
  "surname": "Jackson",
  "defensive_skill": 5,
  "offensive_skill": 4,
  "login": "chris",
  "password": "123456"
}
]

И вот ошибка:

Property 'yob' doesn't exist.

Как видите, во втором объекте моего массива я не указал поле 'yob'. Я ожидал, что для второго объекта будут обновлены все столбцы, кроме «yob». Есть ли что-то, что я делаю неправильно?


person brownie    schedule 15.05.2019    source источник
comment
Вы вставляете в таблицу столбцы или просто столбец json/jsonb? Предположительно, если это табличное отношение, оно сообщит вам, что столбец yob отсутствует, и его потребуется добавить.   -  person Lucas    schedule 15.05.2019
comment
@Lucas Всего восемь столбцов, при обновлении я хочу иметь возможность обновлять каждый из этих столбцов по отдельности. Нет столбца json/jsonb. Я думаю, что моя проблема больше связана с pg-promise.   -  person brownie    schedule 15.05.2019
comment
Исправлено некорректное использование типа skipCB с c => !c.exists || c === undefined; по c => !c.exists || c.value === undefined;. .   -  person vitaly-t    schedule 17.05.2019


Ответы (1)


Причина, по которой это не работает, заключается в том, что логика skip возможна только для однострочных обновлений, как задокументировано в API:

Используется методами update (для одного объекта)...

Синтаксис многострочного обновления не допускает никакой логики пропуска, поэтому вам необходимо указать значение по умолчанию, когда свойство отсутствует, например:

{name: 'yob', skip, def: defaultValue}

defaultValue может быть чем угодно, включая undefined.

В качестве альтернативы вы можете использовать свойство init и динамически возвращать значение.


Итак, в приведенном выше коде, если вы измените объявление столбца на это:

{name: 'yob', skip, def: null}

ваш вызов update будет генерировать:

UPDATE "players" AS t SET "firstname"=v."firstname","surname"=v."surname","yob"=v."yob","defensive_skill"=v."defensive_skill","offensive_skill"=v."offensive_skill","login"=v."login","password"=v."password" FROM (VALUES(25,'Stephen','Harrison',1991,5,3,'harry','123456'),(26,'Chr
is','Jackson',null,5,4,'chris','123456')) AS v("id","firstname","surname","yob","defensive_skill","offensive_skill","login","password")

Как видно из сгенерированного SQL, с таким синтаксисом невозможно пропустить один столбец, поэтому skip игнорируется при многострочном обновлении. Однако вы можете увидеть, как он работает, если вы передаете один объект за раз, но это другой сценарий использования, чем тот, который вы ищете.

person vitaly-t    schedule 15.05.2019
comment
Спасибо за этот точный ответ, я буду обновлять по одной строке за раз, это кажется мне наиболее подходящим решением, так как я не хочу устанавливать значение по умолчанию/инициализацию. - person brownie; 16.05.2019