更新时违反唯一约束

问题描述 投票:0回答:1

我正在 mysql 上使用此模式(sequelize typescript)更新表

@Table
class ItemImage extends Model<ItemImageCreationAttribute> {
  @Index({
    name: "unq-order-idx",
    type: "UNIQUE",
  })
  @ForeignKey(() => Item)
  @Column({
    type: DataType.UUID,
    primaryKey: true,
  })
  itemId!: string;

  @Column({
    type: DataType.STRING,
    primaryKey: true,
  })
  imageName!: string;

  @Index({
    name: "unq-order-idx",
    type: "UNIQUE",
  })
  @Column({
    type: DataType.INTEGER,
    allowNull: false,
  })
  order!: number;

  @BelongsTo(() => Item)
  parentItem!: Item;
}

我正在使用带有事务的续集更新进行更新,我也尝试过将

bulkCreate
updateOnDuplicate

一起使用
const item: Item = (req as any)[Item.name];
const sortedImages = [...item.images].sort((a, b) => a.order - b.order);

// //construct changes
// const changesArray = sortedImages.map((image, i) => ({
//   itemId: item.id,
//   imageName: image.imageName,
//   order: newOrder[i],
// }));

await sequelize.transaction(async (transaction) => {
  await Promise.all(
    sortedImages.map((image, i) =>
      image.update({ order: newOrder[i] }, { transaction })
    )
  );
  // await ItemImage.bulkCreate(changesArray, {
  //   updateOnDuplicate: ["order"],
  //   transaction,
  // });
});

两者都会导致像这样的重复输入错误

original: Error: Duplicate entry '519a6070-af42-48db-a3fc-ec434b0e35f3-5' for key 'itemimages.unq-order-idx'

        code: 'ER_DUP_ENTRY',
        errno: 1062,
        sqlState: '23000',
        sqlMessage: "Duplicate entry '519a6070-af42-48db-a3fc-ec434b0e35f3-5' for key 'itemimages.unq-order-idx'",
        sql: 'UPDATE `ItemImages` SET `order`=?,`updatedAt`=? WHERE `itemId` = ? AND `imageName` = ?',
        parameters: [
          5,
          '2023-12-01 07:59:28',
          '519a6070-af42-48db-a3fc-ec434b0e35f3',
          'image0.webp'
        ]
      },

我尝试检查图像和替换订单,两者都没有问题,图像名称和替换订单是唯一的,具有相同的长度,并且一个项目的所有图像都会立即更新。

删除唯一索引后,错误不再发生并且测试通过(无重复)。

mysql sequelize.js sequelize-typescript
1个回答
0
投票

我最终将订单值更改为负数,然后再将其更改为预期值。请告诉我是否有更好或更简单的方法。

await sequelize.transaction(async (transaction) => {
        await Promise.all(
          sortedImages.map((image, i) =>
            image.update({ order: -image.order }, { transaction })
          )
        );

        await Promise.all(
          sortedImages.map((image, i) =>
            image.update({ order: newOrder[i] }, { transaction })
          )
        );
      });
© www.soinside.com 2019 - 2024. All rights reserved.