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()),
],
},
我正在使用 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()),
],
},