COPY
файла във временна професионална таблица и актуализирайте действителната таблица от там. Като:
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
Ако импортираната таблица съвпада точно с таблицата, която трябва да се актуализира, това може да е удобно:
CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
Създава празна временна таблица, съответстваща на структурата на съществуващата таблица, без ограничения.
Привилегии
До Postgres 10, SQL COPY
изисква привилегии на суперпотребител за това.
В Postgres 11 или по-нова версия има и някои предварително дефинирани роли (по-рано „роли по подразбиране“), които позволяват това. Ръководството:
COPY
именуването на файл или команда е разрешено само на суперпотребители на база данни или потребители, на които е предоставена една от ролитеpg_read_server_files
,pg_write_server_files
илиpg_execute_server_program
[...]
psql метакоманда \copy
работи за всяка db роля. Ръководството:
Извършва фронтенд (клиентско) копие. Това е операция, която изпълнява anSQL
COPY
команда, но вместо сървърът да чете или записва посочения файл, psql чете или записва файла и насочва данните между сървъра и локалната файлова система. Това означава, че достъпността до файловете и привилегиите са тези на локалния потребител, а не на сървъра и не се изискват привилегии на суперпотребител на SQL.
Обхватът на временните таблици е ограничен до една сесия на една роля, така че горното трябва да се изпълни в същата psql сесия:
CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;
Ако скриптирате това в bash команда, не забравяйте да го обвиете в единична psql повикване. Като:
echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
Обикновено се нуждаете от метакомандата \\
за превключване между psql мета команди и SQL команди в psql, но \copy
е изключение от това правило. Отново ръководството:
специални правила за синтактичен анализ се прилагат за
\copy
мета-команда. За разлика от повечето други мета-команди, цялата останала част от реда винаги се приема като аргументи на\copy
и в аргументите не се извършват нито интерполация на променлива, нито разширяване на обратни кавички.
Големи маси
Ако таблицата за импортиране е голяма, може да си струва да увеличите temp_buffers
временно за сесията (първото нещо в сесията):
SET temp_buffers = '500MB'; -- example value
Добавете индекс към временната таблица:
CREATE INDEX tmp_x_id_idx ON tmp_x(id);
И стартирайте ANALYZE
ръчно, тъй като временните таблици не са обхванати от автоматично вакуумиране/автоматичен анализ.
ANALYZE tmp_x;
Свързани отговори:
- Най-добрият начин да изтриете милиони редове по идентификатор
- Как мога да вмъкна общи данни във временна таблица от различни схеми?
- Как да изтрия дублиращи се записи?