Postgresql

PostgreSQL Upsert 不適用於分區表

  • January 3, 2019

有一個這樣的表:

CREATE TABLE aggregated_master (
 "user"       BIGINT,
 type         TEXT,
 date         TIMESTAMP,
 operations   BIGINT,
 amount       NUMERIC,
 PRIMARY KEY ( "user", type, date )
);

該表是許多分區繼承的主表。分區由 DATE 欄位中的 MONTH 完成。例如:2017 年 8 月的分區是 agg_201708,它的 PK 是 pk_agg_201708 在插入之前通常會觸發將插入重定向到正確的分區。

問題是我想在這個表中做一個 UPSERT。DO CONFLICT 部分不起作用。

程式碼首先是這樣的

INSERT INTO aggregated_master (user, type, date, oeprations, amount)
SELECT user, type, date, SUM(ops), SUM(amt)
FROM ...
WHERE ...
GROUP BY USER, TYPE, DATE
ON CONFLICT ON CONSTRAINT pk_aggregated
DO UPDATE SET operations = EXCLUDED.operations
         ,   amount = EXCLUDED.amount

但是後來我注意到約束(pk_aggregated)是主表上的約束,而不是由於觸發器而真正執行插入的子表上的約束。

我將條款 CONFLICT 更改為:

ON CONFLICT (user, type, date)

哪些是PK的欄位,但這也不起作用。

知道如何進行這項工作嗎?

PostgreSQL 11 支持INSERT INTO ... ON CONFLICT分區表:

CREATE TABLE o(id INT PRIMARY KEY, i INT) PARTITION BY RANGE (id);

CREATE TABLE o1 PARTITION OF o FOR VALUES FROM (1) TO (1000);
CREATE TABLE o2 PARTITION OF o FOR VALUES FROM (1000) TO (2000);

INSERT INTO o(id, i) VALUES (1,1),(2,2),(1500,1500);

INSERT INTO o(id, i)
VALUES (1500, 1400), (2,20), (3, 3)
ON CONFLICT (id)
DO UPDATE SET i = EXCLUDED.i;

SELECT * FROM o;

DBFiddle 展示


限制ddl 分區

5.10.2.3。限制

對分區表使用 ON CONFLICT 子句將導致錯誤,因為只能在單個分區上創建唯一或排除約束。不支持在整個分區層次結構中強制執行唯一性(或排除約束)。

已被解除。

引用自:https://dba.stackexchange.com/questions/182580