Haben Sie einen Tisch wie diesen:
CREATE TABLE aggregated_master (
"user" BIGINT,
type TEXT,
date TIMESTAMP,
operations BIGINT,
amount NUMERIC,
PRIMARY KEY ( "user", type, date )
);
Diese Tabelle ist der Master, von dem viele Partitionen erben. Die Partitionen werden bis MONAT im Feld DATUM ausgeführt. Beispiel: Partition für August 2017 wäre agg_201708 und PK wäre pk_agg_201708. Es gibt den üblichen Trigger VOR EINFÜGEN, um die Einfügung auf die richtige Partition umzuleiten.
Die Sache ist, dass ich ein UPSERT in diese Tabelle einfügen möchte. Der DO CONFLICT-Teil funktioniert nicht.
Der Code war zuerst so
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
Aber dann bemerkte ich, dass die Einschränkung (pk_aggregated) diejenige in der Mastertabelle ist und nicht in der untergeordneten Tabelle, in der die Einfügung aufgrund des Triggers wirklich ausgeführt wird.
Ich habe die Klausel CONFLICT geändert in:
ON CONFLICT (user, type, date)
Welches sind die Felder der PK, aber das funktioniert auch nicht.
Irgendeine Idee, wie das funktioniert?
quelle
Antworten:
PostgreSQL 11 unterstützt
INSERT INTO ... ON CONFLICT
mit partitionierten Tabellen:DBFiddle Demo
Einschränkung ddl-Partitionierung
wurde aufgehoben.
quelle
Upsert für partitionierte Tabellen ist in früheren Versionen als Postgres 11 nicht implementiert.
In Postgres 9.6:
Durch deklarative Partitionierung wird das Problem nicht behoben. Postgres 10:
Problemumgehung
("user", type, date)
für alle untergeordneten Tabellen.In Postgres 11 können Sie
ON CONFLICT
für partitionierte Tabellen verwenden, siehe die Antwort von lad2025.quelle