COPY
plik do tymczasowej tabeli pomostowej i zaktualizuj faktyczną tabelę z tego miejsca. Na przykład:
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
Jeśli importowana tabela dokładnie pasuje do tabeli, która ma zostać zaktualizowana, może to być wygodne:
CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
Tworzy pustą tabelę tymczasową pasującą do struktury istniejącej tabeli, bez ograniczeń.
Uprawnienia
Do Postgres 10, SQL COPY
wymaga do tego uprawnień superużytkownika.
W Postgresie 11 lub nowszym istnieją również pewne predefiniowane role (wcześniej „role domyślne”), które na to pozwalają. Instrukcja:
COPY
nazywanie pliku lub polecenia jest dozwolone tylko dla superużytkowników bazy danych lub użytkowników, którym przyznano jedną z ról pg_read_server_files
,pg_write_server_files
lub pg_execute_server_program
[...]
psql meta-polecenie \copy
działa dla dowolnej roli db. Instrukcja:
Wykonuje kopię frontendową (klienta). To jest operacja, która uruchamia COPY
w anSQL polecenie, ale zamiast odczytywania lub zapisywania przez serwer określonego pliku, psql odczytuje lub zapisuje plik i kieruje dane między serwerem a lokalnym systemem plików. Oznacza to, że dostęp do plików i uprawnienia są dostępne dla użytkownika lokalnego, a nie serwera, i nie są wymagane żadne uprawnienia superużytkownika SQL.
Zakres tabel tymczasowych jest ograniczony do jednej sesji jednej roli, więc powyższe musi zostać wykonane w tej samej sesji psql:
CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;
Jeśli piszesz to w poleceniu bash, pamiętaj, aby umieścić to wszystko w pojedynczym połączenie psql. Na przykład:
echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
Zwykle potrzebujesz meta-polecenia \\
przełączać się między metapoleceniami psql a poleceniami SQL w psql, ale \copy
jest wyjątkiem od tej reguły. Instrukcja ponownie:
specjalne zasady parsowania dotyczą \copy
metapolecenie. W przeciwieństwie do większości innych metapoleceń, cała reszta wiersza jest zawsze traktowana jako argumenty \copy
, a w argumentach nie jest wykonywana ani interpolacja zmiennych, ani rozwinięcie cudzysłowów wstecznych.
Duże stoły
Jeśli tabela importów jest duża, warto zwiększyć wartość temp_buffers
tymczasowo na sesję (pierwsza rzecz w sesji):
SET temp_buffers = '500MB'; -- example value
Dodaj indeks do tabeli tymczasowej:
CREATE INDEX tmp_x_id_idx ON tmp_x(id);
I uruchom ANALYZE
ręcznie, ponieważ tabele tymczasowe nie są objęte funkcją autovacuum / auto-analyze.
ANALYZE tmp_x;
Powiązane odpowiedzi:
- Najlepszy sposób na usunięcie milionów wierszy według identyfikatora
- Jak mogę wstawić wspólne dane do tabeli tymczasowej z różnych schematów?
- Jak usunąć zduplikowane wpisy?