如何下载Postgres bytea列作为文件

时间:2011-07-18 09:11:32

标签: file postgresql byte

目前,我在postgres 8.4中存储了许多以bytea格式存储的文件。文件类型为.doc,.odt,.pdf,.txt等。

我可以知道如何下载存储在Postgres中的所有文件,因为我需要进行备份。 我需要它们的原始文件类型而不是bytea格式。

谢谢!

6 个答案:

答案 0 :(得分:38)

一个简单的选择是将COPY命令与encode一起使用到十六进制格式,然后应用xxd shell命令(使用-p 连续hexdump样式开关) 。例如,假设我在样本表的bytea列中有jpg图像:

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

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

我检查过它在实践中有效。

答案 1 :(得分:4)

试试这个:

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

答案 2 :(得分:2)

如果要下载大量数据,则可以先获取行,然后遍历每一行,将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);
}

答案 3 :(得分:0)

最好我知道,bytea to file需要在应用程序级别完成。

(9.1可能会改变文件系统数据包装器的这一点。还有一个lo_export函数,但在这里不适用。)

答案 4 :(得分:0)

   Intent intent = new Intent(mContext, GeofenceReceiver.class);
   Bundle bundle = new Bundle();

   bundle.putParcelable(PROXIMITY_POINT, prox);
   intent.setAction(PROXIMITY_ALERT);
   intent.putExtra(PROXIMITY_DATA, bundle);

   PendingIntent pendingIntent =
          PendingIntent.getBroadcast(mContext, prox.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);

      getLocationManager().addProximityAlert(
          Double.parseDouble(prox.getLat()),
          Double.parseDouble(prox.getLon()),
          prox.getRadius(),
          prox.getExpire(),
          pendingIntent);

答案 5 :(得分:0)

这是我想出的最简单的方法:

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

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