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!
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.
Essaye ça:
COPY (SELECT yourbyteacolumn FROM yourtable WHERE <add your clauses here> ...) TO 'youroutputfile' (FORMAT binary)
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);
}
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; $$
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.)
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
.