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
nebopg_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?