仅 Postgres 支持 deferrable


deferrable 即 推迟约束

一、定义字段时指定

定义:exam考试表里 subject_iddddd 字段关联了 subject 科目表的 id 字段

1、原生 SQL

1.DEFERRABLE INITIALLY DEFERRED
2.DEFERRABLE INITIALLY IMMEDIATE
3.NOT DEFERRABLE

"subject_iddddd" INTEGER REFERENCES "Subjects" ("id") DEFERRABLE INITIALLY IMMEDIATE

注:IMMEDIATE 会在每一个语句执行后进行约束检查,DEFERRED 则只会在事务结束时才检查约束。(DEFERRED 只是推迟检查而不是不检查)

2、Sequelize

1.Sequelize.Deferrable.INITIALLY_DEFERRED

2.Sequelize.Deferrable.INITIALLY_IMMEDIATE

3.Sequelize.Deferrable.NOT

Model defined:

……
        subject_iddddd: {
            type: DataTypes.INTEGER,
            references: {
                model: 'Subjects',
                key: 'id',
                deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE
            }
        }
……

注:此设置仅影响 UNIQUE,PRIMARY KEY,REFERENCES (外键)和 EXCLUDE 约束

二、设置当前事务的临时约束检查

1、原生 SQL

SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }

注1:NOT DEFERRABLE 来说,SET CONSTRAINTS 不生效。

注2:SET CONSTRAINTS ALL 更改所有 DEFERRABLE 约束。

2、Sequelize

sequelize.transaction({
// 推迟所有约束:
deferrable: Sequelize.Deferrable.SET_DEFERRED,

// 推迟具体约束:
deferrable: Sequelize.Deferrable.SET_DEFERRED([‘some_constraint’]),

// 不推迟约束:
deferrable: Sequelize.Deferrable.SET_IMMEDIATE
})

三、应用场景

如果有 province 省份表和 city 城市表,city 表里有 province_id 的字段关联了 province 表的 id 字段。

按照约束,我们合法的操作是先插入安徽省,才能插入合肥市。而先插入合肥市,才能插入安徽省,就会报错:

error: insert or update on table “Citys” violates foreign key constraint “Citys_province_id_fkey"

如何不报错的实现先插入合肥市,才能插入安徽省这个需求呢?

1、给两次插入建立事务

2、用推迟约束

版权声明:本文为xjnotxj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xjnotxj/p/9439442.html