PostgreSQL:事务和外键问题

问题描述 投票:0回答:3

我在表 A 中插入一个值,该值以序列类型作为主键。我想使用查询的返回值作为表 B 的外键...但我收到此消息:

错误:表“tb_midia_pessoa”的插入或更新违反了外键约束“tb_midia_pessoa_id_pessoa_fkey”详细信息:表“tb_pessoa”中不存在键 (id_pessoa)=(30)。 )

如果没有:

我怎样才能做到这一点?
  • 开始新的交易
  • 放弃我的外键约束=O ?

问候! 佩德罗

postgresql transactions foreign-keys
3个回答
22
投票

你可以创建一个可延迟的FK,只需使用DEFERRABLE,也许可以使用INITIALLY DEFERRED,这取决于你。

http://www.postgresql.org/docs/current/static/sql-createtable.html


7
投票

下面的语句允许将不可推迟的约束推迟到事务提交为止。如果您不想更改 FK 定义。

SET CONSTRAINTS ALL DEFERRED;

0
投票

问题中描述的场景不应再引发错误!

这篇文章和已接受的答案不幸地将我引向了错误的道路,这花费了我几个小时的研究 - 希望我可以为你们中的一些人防止这种情况。

至少在 PostgreSQL v14 中,可以将记录插入到表

a
中,并使用其 id 作为表
b
中的引用。如果您至少使用 v14 并看到所描述的错误,则说明有其他问题,这对您来说是事务与外键。

以下示例运行没有错误,这证明问题中的问题不存在(不再) - 至少在问题中描述的简单场景中不存在:

create table tab_a (
  id int primary key generated always as identity,
  foo text
);

create table tab_b (
  id int primary key generated always as identity,
  a_id int NOT NULL references tab_a ON DELETE CASCADE,
  bar text
);

begin;
insert into tab_a (foo) values ('test') returning *;
insert into tab_b (a_id, bar) values (1, 'test') returning *;
commit;

我带着一些代码来到这里,尝试在不同的数据库连接上执行第二个插入语句 - 这显然无法访问事务所在连接上插入的数据。如果您来到这里,请彻底检查一下您的问题是否真的只与问题中给出的内容相关。

© www.soinside.com 2019 - 2024. All rights reserved.