Упорядочить: Как вставить дубликаты указанных столбцов

#mysql #node.js #sequelize.js

Вопрос:

Я хотел создать новую запись, если запись с указанным именем столбца не совпадает или существует, иначе обновите ее.

У меня есть модель с именем AssignedDownloadRoute и определением, которая выглядит так

 AssignedDownloadRoute.init(
  {
    assigned_download_route_id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      allowNull: false,
    },
    route_code: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    assigned_user_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
    assigner_user_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
    reading_period: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    created_modified: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
    }
  },
  {
    sequelize: DBInstance,
    modelName: 'AssignedDownloadRoute',
    tableName: 'assigned_download_route',
    timestamps: false,
  }
);
 

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

 const bulkData = [
  {
    route_code: '123',
    assigned_user_id: 3,
    assigner_user_id: 26,
    reading_period: '202105',
    created_modified: '2021-06-11 06:36:20'
  },
  {
    route_code: '456',
    assigned_user_id: 4,
    assigner_user_id: 32,
    reading_period: '202105',
    created_modified: '2021-06-11 06:36:20'
  }
]
 

Когда я пытаюсь запустить bulkCreate с updateOnDuplicate опцией, она не обновляет существующую запись, а создает новую. Я хочу, чтобы существующие данные обновлялись только assigned_user_id в том случае, assigner_user_id если имя столбца route_code соответствует/уже существует.

 AssignedDownloadRoute.bulkCreate(bulkData, {
   updateOnDuplicate: ['assigned_user_id', 'assigner_user_id'],
});
 

Ответ №1:

Похоже, что только одно поле в вашей модели будет квалифицироваться как уникальное ( assigned_download_route_id ), поскольку оно определено как первичный ключ. Поскольку это значение не включено в вашу полезную нагрузку, в каждой полезной нагрузке нет ничего уникального. Если вы хотите route_code иметь уникальное значение, вы должны соответствующим образом определить его в своей модели с unique: true помощью опции.

 AssignedDownloadRoute.init(
  {
    assigned_download_route_id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      allowNull: false,
    },
    route_code: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
    },
    assigned_user_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
    assigner_user_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
    reading_period: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    created_modified: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
    }
  },
  {
    sequelize: DBInstance,
    modelName: 'AssignedDownloadRoute',
    tableName: 'assigned_download_route',
    timestamps: false,
  }
);
 

Более подробную информацию о вариантах Models наряду с более сложными определениями уникальных ключей (такими как составные ключи) можно прочитать здесь: https://sequelize.org/master/manual/model-basics.html