Tous les termes du glossaire

Upsert avec INSERT ... ON CONFLICT

Comment faire un upsert dans PostgreSQL avec INSERT ... ON CONFLICT ?

INSERT ... ON CONFLICT insère une ligne ou, si cela violait une contrainte d’unicité, met à jour la ligne existante ou l’ignore, en une seule étape atomique.

Upsert signifie insérer ou mettre à jour (insert or update). PostgreSQL l’implémente avec INSERT ... ON CONFLICT : lorsque la nouvelle ligne violerait une contrainte d’unicité ou d’exclusion, DO NOTHING l’ignore et DO UPDATE met à jour la ligne en conflit à la place.

ON CONFLICT DO UPDATE garantit un résultat atomique d’insertion ou de mise à jour, même avec des sessions concurrentes : vous n’avez donc pas besoin d’un SELECT séparé suivi d’un INSERT ou d’un UPDATE. La table spéciale EXCLUDED désigne la ligne proposée pour l’insertion. La cible du conflit, comme (path), doit correspondre à un index ou à une contrainte d’unicité.

Exemple

L’exemple exécute deux fois le même upsert. Le premier insère /home avec 1 vue ; le second se heurte à la clé primaire et ajoute 1 : le décompte final est donc 2.

CREATE TABLE page_views (path text PRIMARY KEY, views bigint NOT NULL);

INSERT INTO page_views VALUES ('/home', 1)
ON CONFLICT (path) DO UPDATE SET views = page_views.views + EXCLUDED.views;
INSERT INTO page_views VALUES ('/home', 1)
ON CONFLICT (path) DO UPDATE SET views = page_views.views + EXCLUDED.views;

SELECT * FROM page_views;

Du SQL simple pour PostgreSQL 16 ou 17 standard, sans aucune extension. Exécutez-le dans une base de données vide que vous pouvez jeter ensuite.

Références

Documentation officielle de PostgreSQL (en anglais).

Termes associés