Sequelize Postgres-如何将ON CONFLICT用于独特功能?

时间:2019-07-12 14:47:13

标签: node.js postgresql sequelize.js

我正在我的NodeJS应用程序中实现Debug.Print。在此之前,我使用的是书面INSERT查询,该查询使用sequelize处理不插入需要唯一值的记录。

ON CONFLICT (field) DO NOTHING

是否可以在模型中定义同一事物的序列化中对此提供支持?也许是更好的处理方法?

本质上,如果const sql = 'INSERT INTO communications (firstname, lastname, age, department, campus, state, message_uuid) VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (message_uuid) DO NOTHING'; const values = [val.firstName, val.lastName, val.age, val.department, val.campus, val.state, message_uuid]; = 123的列中的表中已经存在一条记录,而另一条记录试图插入具有相同值的记录,它将忽略该记录并且不执行任何操作。

2 个答案:

答案 0 :(得分:0)

作为Model.create的第二个参数,您可以提供onConflict道具,请阅读文档

答案 1 :(得分:0)

您可以将public static bulkCreate(records: Array, options: Object): Promise<Array>方法与options.ignoreDuplicates一起使用。

忽略主键的重复值? (MSSQL或Postgres <9.5不支持)

此外,为模型上的unique字段添加message_uuid约束很重要。这样查询将使用Postgres的ON CONFLICT DO NOTHING子句。

例如"sequelize": "^5.21.3"postgres:9.6

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

class Communication extends Model {}
Communication.init(
  {
    firstname: DataTypes.STRING,
    lastname: DataTypes.STRING,
    age: DataTypes.INTEGER,
    message_uuid: {
      type: DataTypes.INTEGER,
      unique: true,
    },
  },
  { sequelize, tableName: 'communications' },
);

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await Communication.create({ firstname: 'teresa', lastname: 'teng', age: 32, message_uuid: 123 });
    // test
    await Communication.bulkCreate([{ firstname: 'teresa', lastname: 'teng', age: 32, message_uuid: 123 }], {
      ignoreDuplicates: true,
    });
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

执行结果:

Executing (default): DROP TABLE IF EXISTS "communications" CASCADE;
Executing (default): DROP TABLE IF EXISTS "communications" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "communications" ("id"   SERIAL , "firstname" VARCHAR(255), "lastname" VARCHAR(255), "age" INTEGER, "message_uuid" INTEGER 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 = 'communications' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "communications" ("id","firstname","lastname","age","message_uuid") VALUES (DEFAULT,$1,$2,$3,$4) RETURNING *;
Executing (default): INSERT INTO "communications" ("id","firstname","lastname","age","message_uuid") VALUES (DEFAULT,'teresa','teng',32,123) ON CONFLICT DO NOTHING RETURNING *;

检查数据库,按预期只有一行。

node-sequelize-examples=# select * from communications;
 id | firstname | lastname | age | message_uuid 
----+-----------+----------+-----+--------------
  1 | teresa    | teng     |  32 |          123
(1 row)