postgresql 如何下载Postgres bytea列作为文件

vdgimpew  于 11个月前  发布在  PostgreSQL
关注(0)|答案(9)|浏览(218)

目前,我有一些文件存储在postgres 8.4作为bytea。文件类型是.doc,.odt,.pdf,.txt等。
我可以知道如何下载所有存储在Postgres的文件,因为我需要做备份。我需要他们在原来的文件类型,而不是字节格式。
谢谢你,谢谢

6ovsh4lw

6ovsh4lw1#

一个简单的选择是使用COPY命令和encode转换为十六进制格式,然后应用xxd shell命令(使用-p continuous hexdump style 开关)。例如,假设我在示例表的bytea列中有jpg图像:

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

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

字符串
正如我所检查的,它在实践中起作用。

i7uq4tfw

i7uq4tfw2#

试试这个:

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

字符串

hivapdat

hivapdat3#

这是我能想到的最简单的方法

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

字符串
-qAt很重要,因为它去除了输出的任何格式。这些选项也可以在psql shell中使用。

doinxwow

doinxwow4#

base64

psql -Aqt -c "SELECT encode(content, 'base64') FROM ..." | base64 -d > file

字符串

xxd

psql -Aqt -c "SELECT encode(content, 'hex') FROM ..." | xxd -p -r > file

ulydmbyx

ulydmbyx5#

如果你有很多数据要下载,那么你可以先获取行,然后遍历每一行,将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);
}

字符串

vyu0f0g1

vyu0f0g16#

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; $$

字符串

ao218c7q

ao218c7q7#

如果你想从本地Windows而不是从服务器执行此操作,则必须单独运行每个语句,并设置PGAdmin和certutil:
1.安装PGAdmin。
1.从运行时文件夹或cd“C:\Program Files\pgAdmin 4\v6\runtime”打开cmd
1.在PGAdmin查询中运行以获取您必须粘贴到cmd中的每个语句:
SELECT 'set PGPASSWORD={PASSWORD} && psql -h {host} -U {user} -d {db name} -Aqt -c“SELECT encode({bytea_column},''base64 '')FROM {table} WHERE id='|| ID|| '”> %a% && CERTUTIL -decode %a%“C:\temp{name_of_the_folder}\FileName - '||联系我们||'('|| TO_CHAR(current_timestamp(),'DD. MM. YYYY,HH24 MI SS ')||').'||联系我们||'"' FROM table WHERE ....;

  • 替换{...}*

它将生成如下内容:

set PGPASSWORD=123  psql -h 192.1.1.1 -U postgres -d my_test_db -Aqt -c "SELECT encode(file_bytea, 'base64') FROM test_table_bytea WHERE id=33" > %a% && CERTUTIL -decode %a% "C:\temp\DB_FILE\FileName - test1 - (06.04.2022,15 42 26).docx"
set PGPASSWORD=123  psql -h 192.1.1.1 -U postgres -d my_test_db -Aqt -c "SELECT encode(file_bytea, 'base64') FROM test_table_bytea WHERE id=44" > %a% && CERTUTIL -decode %a% "C:\temp\DB_FILE\FileName - test2 - (06.04.2022,15 42 26).pdf"

字符串
1.将生成的所有语句复制粘贴到CMD中。文件将保存到本地计算机。

nzk0hqpo

nzk0hqpo8#

据我所知,bytea to file需要在应用程序级别完成。
(9.1可能会用文件系统数据 Package 器contrib改变这一点。还有一个lo_export函数,但它在这里不适用。)

iqih9akk

iqih9akk9#

您可以使用pgsql-fio扩展来实现此功能。

CREATE EXTENSION fio;

select fio_writefile('/home/<your_user>/Downloads', 'your_bytea_content');

字符串

相关问题