web-dev-qa-db-fra.com

Comment télécharger la colonne bygea de Postgres en tant que fichier

Actuellement, j'ai un certain nombre de fichiers stockés dans PostgreSQL 8.4 comme bytea. Les types de fichiers sont .doc, .odt, .pdf, .txt et etc.

Puis-je savoir comment télécharger tous les fichiers stockés dans Postgres car j'ai besoin de faire une sauvegarde. J'ai besoin d'eux dans leur type de fichier d'origine au lieu du format bytea.

Merci!

28
Chong Hsiung

Une option simple consiste à utiliser la commande COPY avec encode au format hexadécimal, puis à appliquer xxd Commande Shell (avec -p commutateur de style hexdump continu ). Par exemple, disons que j'ai une image jpg dans la colonne bytea du tableau d'exemples:

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

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

Comme je l'ai vérifié, cela fonctionne dans la pratique.

40

Essaye ça:

 COPY (SELECT yourbyteacolumn FROM yourtable WHERE <add your clauses here> ...) TO 'youroutputfile' (FORMAT binary)
6
paramecium

Si vous avez beaucoup de données à télécharger, vous pouvez d'abord obtenir les lignes, puis parcourir chacune d'elles en écrivant le champ bytea dans un fichier.

$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);
}
2
brighters
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
dmitriy

Mieux je sais, le bytea au fichier doit être fait au niveau de l'application.

(9.1 pourrait changer cela avec la contribution de l'encapsuleur de données du système de fichiers. Il y a aussi une fonction lo_export, mais elle n'est pas applicable ici.)

0
Denis de Bernardy

Voici la chose la plus simple que j'ai pu trouver:

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

Le -qAt est important car il supprime tout formatage de la sortie. Ces options sont également disponibles dans le shell psql.

0
Chris Cogdon