Punya tabel seperti ini:
CREATE TABLE aggregated_master (
"user" BIGINT,
type TEXT,
date TIMESTAMP,
operations BIGINT,
amount NUMERIC,
PRIMARY KEY ( "user", type, date )
);
Tabel ini adalah master dari mana banyak partisi mewarisi. Partisi dilakukan oleh MONTH di bidang DATE. Sebagai contoh: Partisi untuk Agustus-2017 akan menjadi agg_201708 dan PK-nya adalah pk_agg_201708. Ada pemicu yang biasa SEBELUM INSERT untuk mengarahkan ulang penyisipan ke partisi yang tepat.
Masalahnya adalah saya ingin melakukan UPSERT ke dalam tabel ini. Bagian DO CONFLICT tidak berfungsi.
Kode dulu seperti ini
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
Tapi kemudian saya perhatikan bahwa kendala (pk_aggregated) adalah yang ada di tabel master, dan bukan pada tabel anak di mana penyisipan akan benar-benar dilakukan, karena pemicunya.
Saya mengubah klausa CONFLICT ke:
ON CONFLICT (user, type, date)
Yang merupakan bidang PK, tetapi ini juga tidak berhasil.
Adakah yang tahu bagaimana membuat ini bekerja?
sumber
Jawaban:
PostgreSQL 11 mendukung
INSERT INTO ... ON CONFLICT
dengan tabel dipartisi:Demo DBFiddle
Batasan ddl-partisi
telah diangkat.
sumber
Upsert pada tabel partisi tidak diimplementasikan dalam versi lebih awal dari Postgres 11.
Di Postgres 9.6:
Partisi deklaratif tidak menyelesaikan masalah, Postgres 10:
Penanganan masalah
("user", type, date)
di semua tabel anak,Di Postgres 11 Anda dapat menggunakan
ON CONFLICT
tabel dipartisi, lihat jawaban lad2025.sumber