Вопрос:
В настоящее время у меня есть несколько файлов, хранящихся в postgres 8.4 в качестве байта. Типы файлов:.doc,.odt,.pdf,.txt и т.д.
Могу ли я узнать, как загрузить весь файл, хранящийся в Postgres, потому что мне нужно сделать резервную копию.
Мне нужны они в исходном типе файлов, а не в формате bytea.
Спасибо!
Ответ №1
Один простой вариант – использовать команду COPY с encode в формате hex, а затем примените xxd команду оболочки (с -p непрерывным переключателем стиля hexdump). Например, скажем, у меня есть jpg-изображение в столбце bytea в таблице образцов:
copy (SELECT encode(file, ‘hex’) FROM samples LIMIT 1) TO ‘/home/grzegorz/Desktop/image.hex’ $ xxd -p -r image.hex > image.jpg
Как я проверял, он работает на практике.
Ответ №2
Попробуйте следующее:
COPY (SELECT yourbyteacolumn FROM yourtable WHERE <add your clauses here> …) TO ‘youroutputfile’ (FORMAT binary) Ответ №3
Если у вас много загружаемых данных, вы можете сначала получить строки, а затем перебрать каждый из них, записывая поле bytea в файл.
$resource = pg_connect(‘host=localhost port=5432 dbname=website user=super password=************’); // grab all the user IDs $userResponse = pg_query(‘select distinct(r.id) from resource r join connection c on r.id = c.resource_id_from join resource rfile on c.resource_id_to = rfile.id and rfile.resource_type_id = 10 join file f on rfile.id = f.resource_id join file_type ft on f.file_type_id = ft.id where r.resource_type_id = 38’); // need to work through one by one to handle data while($user = pg_fetch_array($userResponse)){ $user_id = $user[‘id’]; $query = ‘select r.id, f.data, rfile.resource_type_id, ft.extension from resource r join connection c on r.id = c.resource_id_from join resource rfile on c.resource_id_to = rfile.id and rfile.resource_type_id = 10 join file f on rfile.id = f.resource_id join file_type ft on f.file_type_id = ft.id where r.resource_type_id = 38 and r.id = ‘ . $user_id; $fileResponse = pg_query($query); $fileData = pg_fetch_array($fileResponse); $data = pg_unescape_bytea($fileData[‘data’]); $extension = $fileData[‘extension’]; $fileId = $fileData[‘id’]; $filename = $fileId . ‘.’ . $extension; $fileHandle = fopen($filename, ‘w’); fwrite($fileHandle, $data); fclose($fileHandle); } Ответ №4
Лучше всего я знаю, что файл bytea должен выполняться на уровне приложения.
(9.1 может изменить это с помощью файла обложки данных файловой системы. Также есть функция lo_export, но здесь это не применимо.)
Ответ №5DO $$ DECLARE l_lob_id OID; r record; BEGIN for r in select data, filename from bytea_table LOOP l_lob_id:=lo_from_bytea(0,r.data); PERFORM lo_export(l_lob_id,’/home/…’||r.filename); PERFORM lo_unlink(l_lob_id); END LOOP; END; $$ Ответ №6
Вот самая простая вещь, которую я мог придумать:
psql -qAt «select encode(file,’base64′) from files limit 1» | base64 -d
-qAt важен, поскольку он удаляет любое форматирование вывода. Эти опции также доступны внутри оболочки psql.