Sequelize — BulkInsert исключая любые записи, которые уже существуют

#javascript #sequelize.js

#javascript #sequelize.js

Вопрос:

Мне интересно, есть ли способ добавить данные BulkInsert для добавления в базу данных через сеялки, но для исключения любых записей, которые уже существуют.

например: если в базе данных есть пользователь с именем John, и я запускаю сеялку для добавления пользователей в базу данных, а в сеялках есть запись, содержащая имя John, она пропустит эту запись, поскольку она уже существует.

Ответ №1:

Вы можете использовать общедоступный статический асинхронный метод bulkCreate(записи: Массив, параметры: объект): Promise<Array> с options.ignoreDuplicates помощью .

Игнорировать повторяющиеся значения для первичных ключей? (не поддерживается MSSQL или Postgres <9.5)

Важно добавить unique ограничение к name полю.

Вот пример использования "sequelize": "^5.21.3" и postgres:9.6 :

 import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';

class User extends Model {}
User.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
      allowNull: false,
    },
    name: {
      type: DataTypes.STRING,
      unique: true,
    },
  },
  { sequelize },
);

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await User.create({ name: 'John' });
    // insert multiple instances in bulk
    await User.bulkCreate([{ name: 'teresa teng' }, { name: 'slideshowp2' }, { name: 'John' }], {
      fields: ['name'],
      ignoreDuplicates: true,
    });
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();
 

Сначала мы вводим user( John ), затем вставляем несколько пользователей оптом. В массиве есть дублированный user( John ) . Ключевой оператор SQL: ON CONFLICT DO NOTHING , это означает, что если уникальный name конфликт, операция вставки ничего не сделает.

Результат выполнения:

 Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "User" ("id"   SERIAL , "name" VARCHAR(255) UNIQUE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'User' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "User" ("id","name") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","name") VALUES (DEFAULT,'teresa teng'),(DEFAULT,'slideshowp2'),(DEFAULT,'John') ON CONFLICT DO NOTHING RETURNING *;
 

После выполнения проверьте базу данных:

 node-sequelize-examples=# select * from "User";
 id |    name     
---- -------------
  2 | teresa teng
  3 | slideshowp2
  1 | John
(3 rows)
 

Комментарии:

1. что, если имя John существует, тогда мы обновляем данные, связанные с John?