Ответ на ваш актуальный вопрос
Да .Вы можете использовать именованный канал вместо создания файла.Рассмотрим следующую демонстрацию.
Создать схему x
в моей базе данных event
для тестирования:
-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE TABLE x.x (id int, a text);
Создать именованный канал (fifo) из оболочки следующим образом:
postgres@db:~$ mkfifo --mode=0666 /tmp/myPipe
Либо 1) вызовите команду SQL COPY
, используя именованный канал на сервере :
postgres@db:~$ psql event -p5433 -c "COPY x.x FROM '/tmp/myPipe'"
Это получит эксклюзивную блокировку в таблице x.x
в базе данных.Соединение остается открытым, пока fifo не получит данные.Будьте осторожны, не оставляйте это открытым слишком долго!Вы можете назвать это после , когда вы заполнили трубу, чтобы минимизировать время блокировки.Вы можете выбрать последовательность событий.Команда выполняется, как только два процесса связываются с каналом.Первый ждет второго.
или 2) вы можете выполнить SQL из канала на клиенте :
postgres@db:~$ psql event -p5433 -f /tmp/myPipe
Это лучше подходит для вашего случая.Кроме того, никакие таблицы не блокируются, пока SQL не будет выполнен за одно целое.
Bash будет выглядеть заблокированным.Он ждет ввода в трубу.Чтобы сделать все это из одного экземпляра bash, вы можете вместо этого отправить ожидающий процесс в фоновый режим.Например:
postgres@db:~$ psql event -p5433 -f /tmp/myPipe 2>&1 &
В любом случае, из того же самого bash или другого экземпляра, вы можете заполнить трубу сейчас.
Демонстрация тремя строками для варианта 1) :
postgres@db:~$ echo '1 foo' >> /tmp/myPipe; echo '2 bar' >> /tmp/myPipe; echo '3 baz' >> /tmp/myPipe;
(позаботьтесь об использовании вкладок в качестве разделителей или дайте указание COPY принять другой разделитель с помощью WITH DELIMITER 'delimiter_character'
)
Это вызоветожидающий psql с командой COPY для выполнения и возврата:
COPY 3
Демо для варианта 2) :
postgres@db:~$ (echo -n "INSERT INTO x.x VALUES (1,'foo')" >> /tmp/myPipe; echo -n ",(2,'bar')" >> /tmp/myPipe; echo ",(3,'baz')" >> /tmp/myPipe;)
INSERT 0 3
Удалите указанный канал после того, как высделано:
postgres@db:~$ rm /tmp/myPipe
Проверка успешности:
event=# select * from x.x;
id | a
----+-------------------
1 | foo
2 | bar
3 | baz
Полезные ссылки для кода выше
Чтение сжатых файлов с использованием postgres с использованием именованных каналов
Введение в именованные каналы
Лучшая практика запуска bash-скрипта в фоновом режиме
Совет, который вам может понадобиться, а может и не понадобиться
Для больших INSERT
у вас есть лучшие решения, чем отдельные INSERT на строку.Используйте этот вариант синтаксиса:
INSERT INTO mytable (col1, col2, col3) VALUES
(1, 'foo', 'bar')
,(2, 'goo', 'gar')
,(3, 'hoo', 'har')
...
;
Запишите свои операторы в файл и выполните одну массу INSERT
следующим образом:
psql -h remote_server -U username -d database -p 5432 -f my_insert_file.sql
(5432 или любой другой порт, который прослушивает db-кластерon)
my_insert_file.sql
может содержать несколько операторов SQL.Фактически, это обычная практика - восстанавливать / развертывать целые базы данных подобным образом.Обратитесь к руководству по поводу параметра -f
или в bash: man psql
.
Или, если вы можете передать (сжатый) файл на сервер, вы можете использовать COPY , чтобы вставить (распакованные) данные еще быстрее.
Вы также можете выполнить часть или всю обработку внутри PostgreSQL.Для этого вы можете COPY TO
(или INSERT INTO
) временную таблицу и использовать простые операторы SQL для подготовки и, наконец, вставки / обновления ваших таблиц.Я много этим занимаюсь.Помните, что временные таблицы живут и умирают вместе с сеансом.
Вы можете использовать графический интерфейс, например pgAdmin , для удобной работы.Сеанс в окне редактора SQL остается открытым, пока вы не закроете окно.(Следовательно, временные таблицы действуют до тех пор, пока вы не закроете окно.)