PostgreSQL psql 命令行工具和 SET CONSTRAINTS DEFERRED

Mar*_*tus 4 postgresql psql

我正在使用 PostgreSQL 9.1.5 和psql来运行一个 scipt,其中包含各种表中的一系列INSERT语句:

psql -U usernamefoo databasenamefoo -f dml_script.sql
Run Code Online (Sandbox Code Playgroud)

表约束是使用DEFERRABLE选项创建的,脚本本身(上面的文件 dml_script.sql)在有问题的INSERT之前发出以下内容:

SET CONSTRAINTS ALL DEFERRED;                  
INSERT INTO KM_TRANSACTION_GROUPS ..
Run Code Online (Sandbox Code Playgroud)

我已经检查过有关表的特定约束是否已使用DEFRRABLE选项创建:

ALTER TABLE ONLY KM_TRANSACTION_GROUPS ADD CONSTRAINT TRGR_TRGR_FK FOREIGN KEY (TRGR_PARENT_ID) REFERENCES KM_TRANSACTION_GROUPS(TRGR_ID) DEFERRABLE;
Run Code Online (Sandbox Code Playgroud)

然而,运行 DML 脚本失败:

psql:./schema-dml-test.sql:8: ERROR:  insert or update on table "km_transaction_groups" violates foreign key constraint "trgr_trgr_fk"
DETAIL:  Key (trgr_parent_id)=(2) is not present in table "km_transaction_groups".
Run Code Online (Sandbox Code Playgroud)

我的猜测是 psql 将dml_script.sql 中的每个INSERT行视为一个单独的事务。如果这是原因,是否有办法将 dml_script.sql 文件中的 INSERT 语句分组为一个较长的事务(或者可能将整个文件视为一个单个事务),以便在其结束时(当SET CONSTRAINTS ALL DEFERRED的范围;终止),没有违反约束?

否则一些其他方法(除了更改 INSERT 语句的顺序,我有我不想这样做的原因)允许我使用一系列INSERT语句加载表,以便可以暂时停用约束?

小智 5

-1选项将psql导致其包装由指定的文件-fBEGIN..COMMIT块,使它的交易。

否则,将BEGINCOMMIT命令添加到您的脚本中,使其成为单个事务。