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)
我想知道是否有一种方法可以通过播种器将 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)