Sequelize - bulkInsert 排除任何已经存在的条目

Sequelize - bulkInsert excluding any entry's that already exist

我想知道是否有一种方法可以通过播种器将 bulkInsert 数据添加到数据库中,但要排除任何已经存在的条目。

例如: 如果数据库中有名为 John 的用户和我 运行 一个用于将用户添加到数据库的播种器,并且在播种器中有一个包含名称 John 的条目它将跳过该条目,因为它已经存在.

您可以将 public static async bulkCreate(records: Array, options: object): Promise<Array> 方法与 options.ignoreDuplicates 结合使用。

Ignore duplicate values for primary keys? (not supported by MSSQL or Postgres < 9.5)

name 字段添加 unique 约束很重要。

这是一个使用 "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();
  }
})();

我们先播种一个用户(John),然后批量插入多个用户。数组中有一个重复的用户(John)。关键的SQL语句是:ON CONFLICT DO NOTHING,也就是说如果uniquename冲突,插入操作什么都不做。

执行结果:

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,) 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)