Ayez une table comme celle-ci:
CREATE TABLE aggregated_master (
"user" BIGINT,
type TEXT,
date TIMESTAMP,
operations BIGINT,
amount NUMERIC,
PRIMARY KEY ( "user", type, date )
);
Cette table est le maître dont héritent de nombreuses partitions. Les partitions sont effectuées par MOIS dans le champ DATE. Par exemple: la partition pour août 2017 serait agg_201708 et son PK serait pk_agg_201708 Il y a le déclencheur habituel AVANT INSERT pour rediriger l'insertion vers la partition appropriée.
Le fait est que je veux faire un UPSERT dans ce tableau. La partie DO CONFLICT ne fonctionne pas.
Le code était d'abord comme ça
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
Mais ensuite, j'ai remarqué que la contrainte (pk_aggregated) est celle de la table principale, et non de la table enfant où l'insertion sera réellement effectuée, en raison du déclencheur.
J'ai changé la clause CONFLICT en:
ON CONFLICT (user, type, date)
Quels sont les domaines du PK, mais cela ne fonctionne pas non plus.
Une idée comment faire pour que ça marche?
la source
Réponses:
PostgreSQL 11 prend
INSERT INTO ... ON CONFLICT
en charge les tables partitionnées:DBFiddle Demo
Limitation du partitionnement ddl
a été levé.
la source
Upsert sur les tables partitionnées n'est pas implémenté dans les versions antérieures à Postgres 11.
Dans Postgres 9.6:
Le partitionnement déclaratif ne résout pas le problème, Postgres 10:
solution de contournement
("user", type, date)
sur toutes les tables enfants,Dans Postgres 11, vous pouvez utiliser
ON CONFLICT
sur des tables partitionnées, voir la réponse de lad2025.la source