Dubbele sleutels negeren tijdens ‘kopiëren van’ in postgresql

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 PKin 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_tableen dan verwijdert het gedeelte DISTINCT ON (email)ze. De ORDER BYzorgt ervoor dat de gewenste rij eerst komt in de resultatenset en DISTINCTverwijdert 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

Other episodes