#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?