Tener una mesa como esta:
CREATE TABLE aggregated_master (
"user" BIGINT,
type TEXT,
date TIMESTAMP,
operations BIGINT,
amount NUMERIC,
PRIMARY KEY ( "user", type, date )
);
Esta tabla es el maestro del que heredan muchas particiones. Las particiones se realizan por MES en el campo FECHA. Por ejemplo: la partición para agosto de 2017 sería agg_201708 y su PK sería pk_agg_201708. Existe el desencadenante habitual ANTES DE INSERTAR para redirigir la inserción a la partición adecuada.
Lo que pasa es que quiero hacer un UPSERT en esta tabla. La parte DO CONFLICT no funciona.
El código primero fue así
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
Pero luego noté que la restricción (pk_aggregated) es la que está en la tabla maestra, y no en la tabla secundaria donde realmente se realizará la inserción, debido al disparador.
Cambié la cláusula CONFLICT a:
ON CONFLICT (user, type, date)
Cuáles son los campos de la PK, pero esto tampoco funciona.
¿Alguna idea de cómo hacer que esto funcione?
fuente
Respuestas:
PostgreSQL 11 es compatible
INSERT INTO ... ON CONFLICT
con tablas particionadas:DBFiddle Demo
Limitación de particiones ddl
ha sido levantado
fuente
Upsert en tablas particionadas no se implementa en versiones anteriores a Postgres 11.
En Postgres 9.6:
La partición declarativa no resuelve el problema, Postgres 10:
Solución alterna
("user", type, date)
en todas las tablas secundarias,En Postgres 11 puede usarlo
ON CONFLICT
en tablas particionadas, vea la respuesta de lad2025.fuente