使用node-postgres将文件存储在PostgreSQL中

12

我正在尝试使用node-postgres模块将一个小文件存储到Postgres数据库中。我了解到应该使用bytea数据类型来完成这个任务。但问题是当我执行如下操作时:

fs.readFile path, (err, data) ->
    client.query 'UPDATE file_table SET file = $1 WHERE key = $2', [data, key], (e, result) ->
    ....

数据库中文件列的内容为:\x,没有存储任何内容。如果我将数据缓冲区更改为十六进制,即data.toString('hex'),则文件将被存储,但在读取文件时所有格式都将丢失。

使用node-postgres模块正确地将文件存储到PostgreSQL的方法是什么?


1
这里能帮你的是使用 psql 检查插入数据库的数据,看看是否正确。这将告诉你问题是在于正确地插入数据还是读取数据。你还需要提及你的 Pg 版本; 默认的 bytea 格式从 9.0 开始从 escape 改为 hex - Craig Ringer
2
你使用的node-postgres版本是什么?看起来它在一年前就支持了bytea(https://github.com/brianc/node-postgres/pull/38),所以你应该能够直接传递一个缓冲区。 - Craig Ringer
感谢您的评论。我正在使用node-postgres v.0.8.6和Heroku使用的任何版本的postgres。可能是9.x版本。我查看了数据库,数据列中唯一的数据是\x。我通过将字段更改为文本字段并将文件存储为十六进制字符串来找到了解决方法。但我认为这不是一个好主意。 - Clive
1
看起来应该是能工作的;请查看此处的单元测试 https://github.com/drdaeman/node-postgres/commit/f0aa7ccaea735dcd03c62ea017ebec903093c2bf 。也许您需要创建一个包含 DDL 脚本的自包含可编译测试用例,并在发现可以在测试用例中复现问题时向 node-postgres 提交一个 bug? - Craig Ringer
谢谢,我可能会这样做。 - Clive
1个回答

19

关键是将其编码为十六进制并在文件前添加\x。通过返回缓冲区的parseByteA确实支持读回:

https://github.com/brianc/node-postgres/blob/master/lib/textParsers.js

以下是我在postgres 9.2.2和node.js 0.8.16以及node-postgres(npm包='pg')0.11.2中从磁盘读取图像所做的:

      fs.readFile(loc_on_disk, 'hex', function(err, imgData) {
        console.log('imgData',imgData);
        imgData = '\\x' + imgData;
        app.pgClient.query('insert into image_table (image) values ($1)',
                           [imgData],
                           function(err, writeResult) {
          console.log('err',err,'pg writeResult',writeResult);
        });
      });

以及我为了将其重新写出所做的事情

app.get('/url/to/get/', function(req, res, next) {
  app.pgClient.query('select image from image_table limit 1',
                     function(err, readResult) {
    console.log('err',err,'pg readResult',readResult);
    fs.writeFile('/tmp/foo.jpg', readResult.rows[0].image);
    res.json(200, {success: true});
  });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接