Les règles par défaut ajoutent des éléments à l'action en cours :
Mais une règle INSTEAD permet de remplacer l'action :
Donc, je pense que vous voulez spécifier INSTEAD :
CREATE OR REPLACE RULE ignore_duplicate_inserts AS
ON INSERT TO mytable
WHERE (EXISTS ( SELECT mytable.id
FROM mytable
WHERE mytable.id = new.id)) DO INSTEAD NOTHING;
Sans l'INSTEAD, votre règle est essentiellement de dire "faire l'INSERT et ensuite ne rien faire" quand vous voulez dire "au lieu de l'INSERT, ne rien faire" et, autant que je sache, le DO INSTEAD NOTHING
va le faire.
Je ne suis pas un expert des règles PostgreSQL mais je pense que l'ajout du "INSTEAD" devrait fonctionner.
MISE À JOUR :Grâce à araqnid nous savons que :
Donc, une règle ne fonctionnera pas dans cette situation. Cependant, les déclencheurs sont déclenchés pendant COPY FROM afin que vous puissiez écrire un BEFORE INSERT déclencheur qui renverrait NULL lorsqu'il a détecté des lignes en double :
Cela dit, je pense que vous seriez mieux avec "charger tout dans une table temporaire, nettoyer et copier dans la destination finale" d'araqnid serait une solution plus sensée pour une opération de chargement en masse comme vous l'avez fait.