Je dois vider une grande quantité de données d'un fichier vers une table PostgreSQL. Je sais qu'il ne supporte pas 'Ignore' 'replace' etc. comme dans MySql. Presque toutes les publications à ce sujet sur le Web suggéraient la même chose, par exemple, vider les données dans une table temporaire, puis faire un "insérer ... sélectionnez ... où n'existe pas ...".
Cela n’aidera pas dans un cas où les données du fichier contenaient elles-mêmes des clés primaires dupliquées ..___ Tout corps a-t-il une idée de la façon de gérer cela dans PostgreSQL?
P.S. Je le fais à partir d'un programme Java, si cela aide
Utilisez la même approche que celle que vous avez décrite, mais DELETE
(ou groupe, ou modifiez ...) dupliquez PK
dans la table temporaire avant le chargement dans la table principale.
Quelque chose comme:
CREATE TEMP TABLE tmp_table
ON COMMIT DROP
AS
SELECT *
FROM main_table
WITH NO DATA;
COPY tmp_table FROM 'full/file/name/here';
INSERT INTO main_table
SELECT DISTINCT ON (PK_field) *
FROM tmp_table
ORDER BY (some_fields)
Détails: CREATE TABLE AS
, COPY
, DISTINCT ON
PostgreSQL 9.5 a maintenant la fonctionnalité upsert . Vous pouvez suivre les instructions d'Igor, sauf que la dernière instruction INSERT inclut la clause ON CONFLICTO DOH RING.
INSERT INTO main_table
SELECT *
FROM tmp_table
ON CONFLICT DO NOTHING
La réponse d’Igor m’a beaucoup aidé, mais j’ai aussi rencontré le problème mentionné par Nate dans son commentaire. Ensuite, j'ai eu le problème — peut-être en plus de la question ici — que les nouvelles données contenaient non seulement des doublons internes, mais aussi des doublons avec les données existantes. Ce qui a fonctionné pour moi a été le suivant.
CREATE TEMP TABLE tmp_table AS SELECT * FROM newsletter_subscribers;
COPY tmp_table (name, email) FROM stdin DELIMITER ' ' CSV;
SELECT count(*) FROM tmp_table; -- Just to be sure
TRUNCATE newsletter_subscribers;
INSERT INTO newsletter_subscribers
SELECT DISTINCT ON (email) * FROM tmp_table
ORDER BY email, subscription_status;
SELECT count(*) FROM newsletter_subscribers; -- Paranoid again
Les doublons internes et externes deviennent identiques dans le tmp_table
et la partie DISTINCT ON (email)
les supprime. Le ORDER BY
s'assure que la ligne souhaitée vient en premier dans le jeu de résultats et DISTINCT
puis rejette toutes les autres lignes.
Insérer dans une table temporaire regroupée par la clé pour vous débarrasser des doublons
et ensuite insérer s'il n'existe pas