如何在Rails PostgreSQL数据库中创建BLOB列

7

我将尝试在数据库中存储二进制数据。(在 Heroku 上使用 PostgreSQL)

我知道在 PostgreSQL 中有两种不同的存储二进制数据的方式:blob 和 bytea。

当我在迁移中创建表时,

create_table :binaries do |t|
  t.binary :data
end

它在数据库中创建一个类型为bytea的列。
我的问题是...如何创建一个blob类型的记录?
为什么我问呢?似乎当我将一个10字节的文件上传到heroku时,它会将其存储为十六进制值的字符串,并在其前面加上“e”..所以我的10个字节变成了21个。我的10兆文件将变成20兆(还有一个字节),等等...
现在这让我很烦恼,但由于我真的不关心性能。(PM已经打败了我),这不是我最担心的问题。
真正困扰我的是;当我读取数据库的内容时,我得到的是21个字节,而不是10个。那是无法使用的。 所以我的问题又来了...如何在rails/postgresql/heroku环境中创建一个BLOB列?

请不要指出我应该将二进制文件存储为文件。我的任务不是去思考为什么;我的任务只是去做或者... - baash05
2个回答

11

bytea是PostgreSQL的BLOB版本。来自官方文档:

SQL标准定义了一个不同的二进制字符串类型,称为BLOBBINARY LARGE OBJECT。其输入格式与bytea不同,但提供的函数和操作符大多相同。

所以bytea是你想要的类型。就格式而言:

bytea类型支持两种外部格式的输入和输出: PostgreSQL历史上的“转义”格式和“十六进制”格式。两者都总是被接受作为输入。输出格式取决于配置参数bytea_output; 默认为十六进制。(请注意,十六进制格式是在PostgreSQL 9.0中引入的;早期版本和一些工具不理解它。)

所以,你看到的只是用于将数据放入数据库和从数据库中获取数据的文本版本。

这也可能会引起您的兴趣:


谢谢!真的非常感谢!我该如何以二进制形式获取数据?当我输入“a”时,它输出“97”。 - baash05
找到了...并编辑了那个答案...只是为了让下一个新手更容易理解...https://dev59.com/iV7Va4cB1Zd3GeqPJGHL#8541304 - baash05
这似乎是不正确的。Postgres有一个单独的BLOB类型https://wiki.postgresql.org/wiki/BinaryFilesInDB。它与不支持流的bytea不同。 - Chris Nicola
@ChrisNicola 但是 Rails(据我所知)对 PostgreSQL 的大对象系统 一无所知,而 LO 并不是真正的列。 - mu is too short
@ChrisNicola:你想把那个评论扩展成一个答案吗?我会点赞并鼓励OP切换他们的接受,如果LO更适合他们想做的事情。 - mu is too short
显示剩余2条评论

3

Blob存储已经内置于Postgres中,并且使用ActiveRecord适配器进行支持,但是只能通过原始连接和lo_*方法直接使用。您可以使用lo_write、lo_open、lo_close和lo_read来创建和操作Blob。创建Blob会返回一个OID,您可以在模型中引用该Blob。

您可以使用迁移添加此功能。

rails g migration AddFileToModel file:oid

或者像这样直接使用

add_column :users, :avatar, :oid

如果您想查看一个工作示例,您可以查看Carrierwave PostgreSQL gem。您可以基于该代码构建自定义解决方案,也可以直接使用Carrierwave。我目前正在使用它,它运行良好。


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