Использование опции «пропустить» в многострочном обновлении - PullRequest
2 голосов
/ 15 мая 2019

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

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

Вот мой код 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'. Есть ли что-то, что я делаю не так?

1 Ответ

1 голос
/ 16 мая 2019

Причина, по которой это не работает, заключается в том, что логика 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 игнорируется для многострочных обновлений. Однако вы можете увидеть, что это работает, если вы передаете по одному объекту за раз, но это другой сценарий использования, чем тот, который вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...