Sequelize 原始查询更新对象数组作为替换

Sequelize raw query update array of objects as replacements

我正在使用 sequelize (postgres),我需要像这样正确地转义查询:

`
       UPDATE "Pets"
       SET "name" = CASE LOWER("name")
         ${input.pets
            .map((pet) => `WHEN '${pet.name.toLowerCase()}' THEN '${pet.newName}'`)
            .join('\n')}
          ELSE "name"
          END
        WHERE LOWER("name") IN(${input.pets
          .map((pet) => `'${pet.name.toLowerCase()}'`)
          .join(',')});
`

样本input.pets:

[{ name: "rocky", newName: "leo" }]

有谁知道如何通过替换实现这一点?

我在 github 上找到了一个帖子,它提出了这样的建议:

let data = [ [ 252456, 1, 55, '0' ],
[ 357083, 1, 56, '0' ],
[ 316493, 1, 57, '0' ] ];

db.query(
  `INSERT INTO product (a, b) VALUES ${data.map(a => '(?)').join(',')};`,
  {
     replacements: data,
     type: Sequelize.QueryTypes.INSERT
  }
);

但是,这里使用的是二维数组,而不是对象数组。有没有办法从数组中访问单个属性?当我尝试这样的事情时

`
       UPDATE "Pets"
       SET "name" = CASE LOWER("name")
         ${input.pets
            .map((_pet) => `WHEN ? THEN ?`)
            .join('\n')}
          ELSE "name"
          END
        WHERE LOWER("name") IN(${input.pets
          .map((_pet) => `?`)
          .join(',')});
`,
    { type: QueryTypes.UPDATE, replacements: input.pets },

第一个?原来是整个对象。有没有办法访问它的属性? 我也尝试将 input.pets 转换为二维数组,但仍然无法像上面插入的示例那样工作。

预先感谢您的时间

    const names = input.pets.map((pet) => pet.name);
    const newNames = input.pets.map((pet) => pet.newName);

`
        UPDATE "Pets"
        SET "name" = CASE LOWER("name")
          ${names.map((_) => `WHEN LOWER(:names) THEN :newNames`).join('\n')}
              ELSE "name"
              END
        WHERE LOWER("name") IN(${names.map((_) => `LOWER(:names)`).join(',')});
`,
      { replacements: { names, newNames } },

这行得通。在这种情况下,最好使用更简单的数据结构。我发现的另一个选择是使用 sequelize.escape() built-in 函数,但没有记录,所以我决定不

编辑: 经过一些测试后,这有效,但仅适用于输入

中的一个对象

如果输入看起来像这样:

[
        { name: "rocky", newName: "fafik" }
        { name: "asd", newName: "qwerty" }
]

然后我得到这样的查询:

WHEN LOWER('rocky', 'asd') THEN 'fafik', 'qwerty'
WHEN LOWER('rocky', 'asd') THEN 'fafik', 'qwerty'

所以它不会遍历数组。问题仍然存在,如何访问单个属性,无论是从数组还是对象?

EDIT2:最终答案

sequelize.query(
  `
    UPDATE "Pets"
    SET "name" = CASE LOWER("name")
      ${input.pets.map(() => `WHEN ? THEN ?`).join('\n')}
         ELSE "name"
         END
    WHERE LOWER("name") IN(?);
  `,
  {
    replacements: [
      ...input.pets.flatMap((x) => [x.name.toLocaleLowerCase(), x.newName]),
      input.pets.map((x) => x.name.toLocaleLowerCase()),
    ],
  },