【问题标题】:Sequelize: How to exclude fields from being updated by `upsert` methodSequelize:如何通过“upsert”方法排除字段更新
【发布时间】:2019-11-14 19:39:19
【问题描述】:

情况

  • 我正在使用 Sequelize (v5.8.9) upsert 方法插入/更新记录 在具有唯一索引的表中。
  • 我使用的是 Postgres 11,每个表都有 createdAtcreatedByupdatedAtupdatedBy 字段。

问题

当我在表中插入一条记录时,Sequelize 会生成如下 SQL:

CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert
(OUT created boolean, OUT primary_key text)  AS $func$ 
BEGIN INSERT INTO "table1" ("name","created_by","updated_by","created_at","updated_at") 
VALUES (...) RETURNING "id" INTO primary_key; created := true; 
EXCEPTION WHEN unique_violation THEN 
UPDATE "table1" SET ...,"created_by"='user1',"updated_by"='user1',"updated_at"='2019-07-03 23:45:05.872 +00:00' 
WHERE ("id" IS NULL OR "name" = '...') 
RETURNING "tag_id" INTO primary_key; created := false; 
END; $func$ LANGUAGE plpgsql; 
SELECT * FROM pg_temp.sequelize_upsert();

我们可以看到,Sequelize 在记录已经存在时更新 created_by 字段(unique_violation)。

我找不到可以将 created_by 从更新中排除的解决方案或解决方法。我也喜欢坚持upsert,因为它比通过选择检查存在然后插入或更新更有效。任何建议表示赞赏。

我知道我可以指定fields 参数,但按照doc

The fields to insert / update. Defaults to all changed fields

但在我的情况下,如果 upsert 的插入成功,我确实需要插入 created_by 字段。

我也在考虑在 Sequelize 中提出一个功能请求,以便在模型定义中我可以注册一个应该从所有更新(实例保存、Model.update、upsert 等)中排除的字段列表,而不仅仅是@987654332 @。

【问题讨论】:

    标签: sequelize.js


    【解决方案1】:

    在 upsert 方法中,您可以使用 fields 键将对象作为第二个参数传递,以提供要插入或更新的字段列表。

    查看此文档:

    http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-upsert

    db.model.upsert({
      ...yourData
    },{
      fields: [...NameOfFieldsToBeUpdated]
    }).then(function(test){})
    

    【讨论】:

    • 感谢您的信息,抱歉我没有说清楚。 fields 适用于创建和更新。在我的情况下,如果 upsert 是插入,我确实需要插入 created_by
    猜你喜欢
    • 2017-01-16
    • 2014-11-15
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    相关资源
    最近更新 更多