Je vais donner un exemple simplifié de mon problème. J'ai deux tables: reviews
et users
.Est-ce la manière correcte d'insérer INSERT ON CONFLICT dans Postgres?
reviews
est mis à jour avec un tas de commentaires que les utilisateurs publient. Le processus qui récupère les avis renvoie également des informations pour l'utilisateur qui l'a soumis (et certaines données utilisateur changent fréquemment).
Je veux mettre à jour users
chaque fois que je mets à jour reviews
, en vrac, en utilisant COPY
. Le problème se pose pour users
lorsque les données récupérées contient deux ou plusieurs avis du même utilisateur. Si je fais un simple INSERT ON CONFLICT
, je pourrais se retrouver avec des erreurs depuis et INSERT
instruction ne peut pas mettre à jour la même ligne deux fois. Un SELECT DISTINCT
résoudrait ce problème, mais je veux également garantir que j'insère les dernières données dans la table users
. C'est comme ça que je le fais. Gardez à l'esprit que je le fais en vrac:
1. Créez une table temporaire afin que nous puissions COPY
à partir de/à partir de ce.
CREATE TEMPORARY TABLE users_temp (
id uuid,
stat_1 integer,
stat_2 integer,
account_age_in_mins integer);
2. COPY
données dans la table temporaire
COPY users_temp (
id,
stat_1,
stat_2,
account_age_in_mins) FROM STDIN CSV ENCODING 'utf-8';
3. Table de verrouillage users
et effectuer INSERT ON CONFLICT
LOCK TABLE users in EXCLUSIVE MODE;
INSERT INTO users SELECT DISTINCT ON (1)
users_temp.id,
users_temp.stat_1,
users_temp.stat_2,
users_temp.account_age_in_mins
FROM users_temp
ORDER BY 1, 4 DESC, 2, 3
ON CONFLICT (id) DO UPDATE
SET
stat_1 = EXCLUDED.stat_1,
stat_2 = EXCLUDED.stat_2,
account_age_in_mins = EXCLUDED.account_age_in_mins';
La raison pour laquelle je fais un SELECT DISTINCT
et un ORDER BY
à l'étape 3) est parce que je:
- veux seulement retourner une instance des lignes en double.
- À partir de ces duplicates assurez-vous que je reçois l'enregistrement le plus à jour par en triant sur le
account_age_in_mins
.
Est-ce la bonne méthode pour atteindre mon objectif?
Ça a l'air plutôt bien. –
@LaurenzAlbe Bon à entendre. Tout ce que tu ferais différemment? – Petar
À première vue, non. –