繁体   English   中英

Postgres 在单个事务中插入之前删除

[英]Postgres delete before insert in single transaction

PostgreSQL 数据库:v 9.4.24

create table my_a_b_data ... // with a_uuid, b_uuid, and c columns

注意:my_a_b_data 保留对 a 和 b 表的引用。 所以它保留了a和b的uuid。

其中: primary key (a_uuid, b_uuid)

还有一个索引

create unique index my_a_b_data_pkey
    on my_a_b_data (a_uuid, b_uuid);

类似 Java jdbc 的代码中,在一个事务的范围内: (start() -> [code (delete, insert)] ->commit()]) ( org.postgresql:postgresql:42.2.5 driver )

delete from my_a_b_data where b_uuid = 'bbb';
insert into my_a_b_data (a_uuid, b_uuid, c) values ('aaa', 'bbb', null);

我发现插入失败了,因为删除还没有删除。 所以它失败了,因为它不能被复制。

问: DB 不能在一个事务中进行删除和插入是PostgreSQL中的某种限制吗,因为 PostgreSQL 在执行删除提交之前不会更新其索引,因此插入将失败,因为 id 或键(无论我们使用什么)已经存在于索引中?

可能的解决方案是什么? 分成两笔交易?

更新:订单完全相同。 当我在 SQL 控制台中单独测试 sql 时。 它工作正常。 我们使用 JDBI 库 v 5.29。

它看起来像这样:

 @Transaction
 @SqlUpdate("insert into my_a_b_data (...; // similar for the delete
 public abstract void addB() ..

所以在代码中:

this.begin();
this.deleteByB(b_id);
this.addB(a_id, b_id);
this.commit();

我在插入重复值时遇到了类似的问题,我通过使用 Insert 和 Update 而不是 Delete 解决了这个问题。 我在 Python 上创建了这个过程,但你可以重现它:

  1. 首先,你创建一个临时表,就像你要插入值的目标表,不同的是这个表在提交后被删除。

     CREATE TEMP TABLE temp_my_a_b_data (LIKE public.my_a_b_data INCLUDING DEFAULTS) ON COMMIT DROP;
  2. 我创建了一个 CSV(我必须将不同的数据合并到输入中),其中包含我想在我的表中输入/插入的值,并且我使用COPY函数将它们插入到 temp_table ( temp_my_a_b_data ) 中。

    我在这篇与 Java 和 COPY PostgreSQL - \copy 命令相关的帖子中找到了这段代码:

     String query ="COPY tmp from 'E://load.csv' delimiter ','";
  3. 使用 INSERT INTO 但使用ON_CONFLICT子句,您可以决定在由于指定约束而无法完成插入时执行操作,在下面的情况下我们进行更新:

     INSERT INTO public.my_a_b_data SELECT * FROM temp_my_a_b_data ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE SET a_uuid = EXCLUDED.a_uuid, b_uuid = EXCLUDED. c = EXCLUDED.c;`

注意事项:

我不确定,但您可以在不使用前面的步骤、临时表或从中复制的情况下执行第三步。 您可以只循环遍历这些值:

INSERT INTO public.my_a_b_data VALUES(value1, value2, null) 
ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE 
   SET a_uuid = EXCLUDED.a_uuid, 
       b_uuid = EXCLUDED.b_uuid, c = EXCLUDED.c;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM