PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come aggiornare le righe selezionate con valori da un file CSV in Postgres?

COPY il file in una tabella di staging temporanea e da lì aggiornare la tabella effettiva. Come:

CREATE TEMP TABLE tmp_x (id int, apple text, banana text); -- but see below

COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);

UPDATE tbl
SET    banana = tmp_x.banana
FROM   tmp_x
WHERE  tbl.id = tmp_x.id;

DROP TABLE tmp_x; -- else it is dropped at end of session automatically

Se la tabella importata corrisponde esattamente alla tabella da aggiornare, può essere conveniente:

CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;

Crea una tabella temporanea vuota che corrisponde alla struttura della tabella esistente, senza vincoli.

Privilegi

Fino a Postgres 10, SQL COPY richiede privilegi di superutente per questo.
In Postgres 11 o versioni successive, ci sono anche alcuni ruoli predefiniti (precedentemente "ruoli predefiniti") per consentirlo. Il manuale:

COPY la denominazione di un file o di un comando è consentita solo ai superuser del database o agli utenti a cui è concesso uno dei ruoli pg_read_server_files ,pg_write_server_files o pg_execute_server_program [...]

Il psql meta-comando \copy funziona per qualsiasi ruolo db. Il manuale:

Esegue una copia front-end (client). Questa è un'operazione che esegue un SQL COPY comando, ma invece di leggere o scrivere il file specificato dal server, psql legge o scrive il file e instrada i dati tra il server e il file system locale. Ciò significa che l'accessibilità ai file e i privilegi sono quelli dell'utente locale, non del server, e non sono richiesti privilegi di superutente SQL.

L'ambito delle tabelle temporanee è limitato a una singola sessione di un singolo ruolo, quindi quanto sopra deve essere eseguito nella stessa sessione psql:

CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;

Se stai scrivendo questo in un comando bash, assicurati di racchiuderlo tutto in un singolo chiamata psql. Come:

echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql

Normalmente, hai bisogno del meta-comando \\ per passare dai meta comandi psql ai comandi SQL in psql, ma \copy è un'eccezione a questa regola. Il manuale di nuovo:

regole speciali di analisi si applicano a \copy metacomando. A differenza della maggior parte degli altri meta-comandi, l'intero resto della riga viene sempre considerato come argomenti di \copy , e negli argomenti non vengono eseguite né l'interpolazione delle variabili né l'espansione delle virgolette.

Tavoli grandi

Se la tabella di importazione è grande, potrebbe essere utile aumentare temp_buffers temporaneamente per la sessione (prima cosa nella sessione):

SET temp_buffers = '500MB';  -- example value

Aggiungi un indice alla tabella temporanea:

CREATE INDEX tmp_x_id_idx ON tmp_x(id);

Ed esegui ANALYZE manualmente, poiché le tabelle temporanee non sono coperte da autovacuum/auto-analyze.

ANALYZE tmp_x;

Risposte correlate:

  • Il modo migliore per eliminare milioni di righe per ID
  • Come posso inserire dati comuni in una tabella temporanea da schemi disparati?
  • Come eliminare le voci duplicate?