Ik moet een grote hoeveelheid gegevens uit een bestand dumpen naar een tabel PostgreSQL. Ik weet dat het ‘Negeren’, ‘vervangen’ enz. niet ondersteunt, zoals gedaan in MySql. Bijna alle berichten hierover op het web suggereerden hetzelfde, zoals het dumpen van de gegevens naar een tijdelijke tabel en vervolgens een ‘insert … select … waar niet bestaat…’ doen.
Dit zal in één geval niet helpen, waarbij de bestandsgegevens zelf dubbele primaire sleutels bevatten.
Heeft iemand een idee hoe dit in PostgreSQL aan te pakken?
P.S. Ik doe dit vanuit een java-programma, als het helpt
Antwoord 1, autoriteit 100%
Gebruik dezelfde aanpak als je hebt beschreven, maar DELETE
(of groepeer, of wijzig …) dupliceer PK
in de tijdelijke tabel voordat je deze naar de hoofdtabel laadt.
Zoiets als:
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)
Details: CREATE TABLE AS
, COPY
, DISTINCT ON
Antwoord 2, autoriteit 59%
PostgreSQL 9.5 heeft nu upsert-functionaliteit. Je kunt de instructies van Igor volgen, behalve dat de laatste INSERT de clausule ON CONFLICT DO NOTHING bevat.
INSERT INTO main_table
SELECT *
FROM tmp_table
ON CONFLICT DO NOTHING
Antwoord 3, autoriteit 17%
Het antwoord van Igor heeft me veel geholpen, maar ik kwam ook het probleem tegen dat Nate in zijn opmerking noemde. Toen had ik het probleem – misschien naast de vraag hier – dat de nieuwe gegevens niet alleen intern duplicaten bevatten, maar ook duplicaten met de bestaande gegevens. Wat voor mij werkte, was het volgende.
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
Zowel interne als externe duplicaten worden hetzelfde in de tmp_table
en dan verwijdert het gedeelte DISTINCT ON (email)
ze. De ORDER BY
zorgt ervoor dat de gewenste rij eerst komt in de resultatenset en DISTINCT
verwijdert vervolgens alle volgende rijen.
Antwoord 4
Invoegen in een tijdelijke tabel, gegroepeerd op de sleutel, zodat u de duplicaten verwijdert
en dan invoegen indien niet bestaat