web-dev-qa-db-fra.com

Insertion en masse, mise à jour en cas de conflit (augmentation en masse) sur Postgres

J'écris un programme d'exploration de données, qui insère en vrac des données utilisateur.

Le SQL actuel n'est qu'une simple insertion en bloc:

insert into USERS(
    id, username, profile_picture)
select unnest(array['12345']),
    unnest(array['Peter']),
    unnest(array['someURL']),
on conflict (id) do nothing;

Comment faire une mise à jour en cas de conflit? J'ai essayé:

...
    unnest(array['Peter']) as a,
    unnest(array['someURL']) as b,
on conflict (id) do 
update set
    username = a,
    profile_picture = b;

Mais ça jette There is a column named "a" in table "*SELECT*", but it cannot be referenced from this part of the query. Erreur.

MODIFIER :

Le tableau de USERS est très simple:

create table USERS (
    id      text not null primary key,
    username    text,
    profile_picture text
);
31
MK Yung

Il s'avère qu'une table spéciale nommée excluded contient la ligne à insérer (nom étrange cependant)

insert into USERS(
    id, username, profile_picture)
select unnest(array['12345']),
    unnest(array['Peter']),
    unnest(array['someURL'])
on conflict (id) do 
update set
    username = excluded.username,
    profile_picture = excluded.profile_picture;

http://www.postgresql.org/docs/9.5/static/sql-insert.html#SQL-ON-CONFLICT

Les clauses SET et WHERE dans ON CONFLICT DO UPDATE ont accès à la ligne existante en utilisant le nom de la table (ou un alias), et aux lignes proposées pour l'insertion en utilisant la table spéciale exclue ...

69
MK Yung