Использование открытого подключения к базе данных PostgreSQL в BASH? - PullRequest
2 голосов
/ 08 февраля 2012

Мне нужно использовать BASH для подключения к нашему серверу баз данных PostgreSQL 9.1 для выполнения различных операторов SQL.

У нас проблема с производительностью, вызванная многократным открытием / закрытием слишком большого количества подключений к базе данных (сейчас мы отправляем каждый оператор в команду psql).

Я смотрю на возможность поддержания открытого соединения с базой данных для блока операторов SQL с использованием именованных каналов.

У меня проблема в том, что когда я открываю соединение и выполняю оператор SQL, я не знаю, когда прекратить чтение из psql. Я думал о синтаксическом анализе вывода, чтобы найти подсказку, хотя я не знаю, безопасно ли это, учитывая возможность того, что символ может быть встроен в вывод SELECT.

У кого-нибудь есть предложения?

Вот упрощенный пример того, что я имею до сих пор ...

#!/bin/bash

PIPE_IN=/tmp/pipe.in
PIPE_OUT=/tmp/pipe.out

mkfifo $PIPE_IN $PIPE_OUT
psql -A -t jkim_edr_md_xxx_db < $PIPE_IN > $PIPE_OUT &
exec 5> $PIPE_IN; rm -f $PIPE_IN
exec 4< $PIPE_OUT; rm -f $PIPE_OUT

echo 'SELECT * FROM some_table' >&5

# unfortunately, this loop blocks
while read -u 4 LINE
do
    echo LINE=$LINE
done

Ответы [ 3 ]

1 голос
/ 08 февраля 2012

Используйте --file=filename для пакетного выполнения.

В зависимости от вашей потребности в управлении потоком вы можете использовать другой язык с более гибким API БД (мой выбор - Pythonздесь, но используйте все, что работает).

0 голосов
/ 10 февраля 2012

в psql Вы можете использовать

\o YOUR_PIPE
SELECT whatever;
\o

, который откроет, напишет и закроет трубу. Ваш BASH-фу выглядит намного сильнее, чем мой, поэтому я позволю вам проработать детали:)

0 голосов
/ 08 февраля 2012
            echo >&5 "SELECT * FROM some_table"

должно читаться

            echo 'SELECT * FROM some_table' >&5

Оператор перенаправления >& следует после параметров до echo;а также, если вы используете "" кавычки, некоторые знаки препинания могут быть обработаны специально оболочкой, что впоследствии приведет к появлению грязных и таинственных ошибок.С другой стороны, цитирование ' будет… безобразным.SELECT * FROM some_table WHERE foo=\'Can\'\'t read\''

Возможно, вы также захотите создать эти трубы где-нибудь безопаснее, чем /tmp.Существует серьезная проблема с дырой в безопасности, когда кто-то еще на хосте может взломать ваше соединение.Попробуйте создать папку, такую ​​как /var/run/yournamehere/ с привилегиями 0700, и создайте в ней каналы, в идеале с именами, такими как PIPE_IN=/var/run/jinkimsqltool/sql.pipe.in.$$ - $$, которые будут идентификатором вашего процесса, поэтому сценарии, выполняемые одновременно, не будут перекрывать друг друга.(Чтобы усугубить дыру в безопасности, rm -rf не требуется для канала, но умный взломщик мог бы использовать это выделение привилегий для злоупотребления -r там. Достаточно только rm -f.)

...