Как скачать колонку Postgres bytea в виде файла - PullRequest
27 голосов
/ 18 июля 2011

В настоящее время у меня есть несколько файлов, которые хранятся в postgres 8.4 как bytea. Типы файлов: .doc, .odt, .pdf, .txt и т. Д.

Могу ли я узнать, как загрузить все файлы, хранящиеся в Postgres, потому что мне нужно сделать резервную копию. Они нужны мне в оригинальном типе файла, а не в формате bytea.

Спасибо!

Ответы [ 5 ]

38 голосов
/ 18 июля 2011

Один простой вариант - использовать команду COPY с encode в шестнадцатеричном формате, а затем применить xxd команду оболочки (с -p непрерывный шестнадцатеричный стиль переключатель).Например, допустим, у меня есть изображение jpg в столбце bytea в таблице сэмплов:

\copy (SELECT encode(file, 'hex') FROM samples LIMIT 1) TO
    '/home/grzegorz/Desktop/image.hex'

$ xxd -p -r image.hex > image.jpg

Как я проверял, это работает на практике.

5 голосов
/ 29 июня 2016

Попробуйте это:

 COPY (SELECT yourbyteacolumn FROM yourtable WHERE <add your clauses here> ...) TO 'youroutputfile' (FORMAT binary)
2 голосов
/ 17 июня 2014

Если вам нужно загрузить много данных, вы можете сначала получить строки, а затем перебирать каждую из них, записывая поле байта в файл.

$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);
}
0 голосов
/ 06 февраля 2019
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; $$
0 голосов
/ 18 июля 2011

Насколько я знаю, байта в файл должна быть сделана на уровне приложения.

(9.1 может изменить это с помощью обертки данных файловой системы. Существует также функция lo_export, но она здесь не применима.)

...