sql >> Databáze >  >> RDS >> PostgreSQL

Jak aktualizovat vybrané řádky hodnotami ze souboru CSV v Postgresu?

COPY soubor do dočasné pracovní tabulky a odtud aktualizujte skutečnou tabulku. Jako:

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

Pokud importovaná tabulka přesně odpovídá tabulce, která má být aktualizována, může to být výhodné:

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

Vytvoří prázdnou dočasnou tabulku odpovídající struktuře existující tabulky bez omezení.

Oprávnění

Až do Postgres 10, SQL COPY vyžaduje k tomu oprávnění superuživatele.
V Postgres 11 nebo novějším jsou také některé předdefinované role (dříve „výchozí role“), které to umožňují. Manuál:

COPY pojmenování souboru nebo příkazu je povoleno pouze superuživatelům databáze nebo uživatelům, kteří mají přidělenou jednu z rolí pg_read_server_files ,pg_write_server_files nebo pg_execute_server_program [...]

Soubor psql meta-příkaz \copy funguje pro jakoukoli roli db. Manuál:

Provede frontendovou (klientskou) kopii. Toto je operace, která spouští anSQL COPY příkaz, ale místo toho, aby server četl nebo zapisoval zadaný soubor, psql čte nebo zapisuje soubor a směruje data mezi serverem a lokálním souborovým systémem. To znamená, že přístupnost a oprávnění k souborům patří místnímu uživateli, nikoli serveru, a nejsou vyžadována žádná oprávnění superuživatele SQL.

Rozsah dočasných tabulek je omezen na jednu relaci jedné role, takže výše uvedené musí být provedeno ve stejné relaci psql:

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

Pokud to skriptujete v příkazu bash, nezapomeňte to vše zabalit do jednoho volání psql. Jako:

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

Normálně potřebujete meta-příkaz \\ pro přepínání mezi metapříkazy psql a příkazy SQL v psql, ale \copy je výjimkou z tohoto pravidla. Znovu manuál:

speciální pravidla analýzy platí pro \copy meta-příkaz. Na rozdíl od většiny ostatních meta-příkazů je celý zbytek řádku vždy považován za argumenty \copy a v argumentech se neprovádí ani proměnná interpolace, ani expanze zpětných uvozovek.

Velké stoly

Pokud je importní tabulka velká, může se vyplatit zvýšit temp_buffers dočasně pro relaci (první věc v relaci):

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

Přidejte index do dočasné tabulky:

CREATE INDEX tmp_x_id_idx ON tmp_x(id);

A spusťte ANALYZE ručně, protože dočasné tabulky nejsou pokryty automatickým vakuem / automatickou analýzou.

ANALYZE tmp_x;

Související odpovědi:

  • Nejlepší způsob, jak odstranit miliony řádků podle ID
  • Jak mohu do dočasné tabulky vložit běžná data z různých schémat?
  • Jak odstranit duplicitní záznamy?


  1. Načítání textu UTF-8 z MySQL v R vrací ????

  2. Jak mohu vložit mnoho řádků do tabulky MySQL a vrátit nová ID?

  3. Hierarchické dotazy v MySQL

  4. SQLite unie