How to download Postgres bytea column as file

前端 未结 6 1803
甜味超标
甜味超标 2020-12-24 06:13

Currently, i have a number of files stored in postgres 8.4 as bytea. The file types are .doc, .odt, .pdf, .txt and etc.

May i know how to download all the file store

相关标签:
6条回答
  • 2020-12-24 06:46

    One simple option is to use COPY command with encode to hex format and then apply xxd shell command (with -p continuous hexdump style switch). For example let's say I have jpg image in bytea column in samples table:

    \copy (SELECT encode(file, 'hex') FROM samples LIMIT 1) TO
        '/home/grzegorz/Desktop/image.hex'
    
    $ xxd -p -r image.hex > image.jpg
    

    As I checked it works in practice.

    0 讨论(0)
  • 2020-12-24 06:48
    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 讨论(0)
  • 2020-12-24 06:50

    Try this:

     COPY (SELECT yourbyteacolumn FROM yourtable WHERE <add your clauses here> ...) TO 'youroutputfile' (FORMAT binary)
    
    0 讨论(0)
  • 2020-12-24 06:58

    Best I'm aware, bytea to file needs to be done at the app level.

    (9.1 might change this with the filesystem data wrapper contrib. There's also a lo_export function, but it is not applicable here.)

    0 讨论(0)
  • 2020-12-24 07:01

    If you have a lot of data to download then you can get the lines first and then iterate through each one writing the bytea field to file.

    $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 讨论(0)
  • 2020-12-24 07:04

    Here's the simplest thing I could come up with:

    psql -qAt "select encode(file,'base64') from files limit 1" | base64 -d
    

    The -qAt is important as it strips off any formatting of the output. These options are available inside the psql shell, too.

    0 讨论(0)
提交回复
热议问题