Как загрузить столбец postgres bytea в файл
В настоящее время у меня есть несколько файлов, хранящихся в 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, но здесь это не применимо.)
Ответ 5
DO $$
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
.