【问题标题】:How to insert (raw bytes from file data) using a plain text script如何使用纯文本脚本插入(来自文件数据的原始字节)
【发布时间】:2014-02-06 11:22:59
【问题描述】:

数据库:Postgres 9.1

我有一个名为 logos 的表,定义如下:

create type image_type as enum ('png');
create table logos (
  id UUID primary key,
  bytes bytea not null,
  type image_type not null,
  created timestamp with time zone default current_timestamp not null
);
create index logo_id_idx on logos(id);

我希望能够通过 2 种方式将记录插入到此表中。

在表格中插入行的第一种(也是最常见的)方式是用户将通过 html 文件上传表单提供 PNG 图像文件。在服务器上处理请求的代码将接收一个包含 PNG 图像文件中数据的字节数组,并使用与 here 解释的内容非常相似的东西在表中插入一条记录。互联网上有很多关于如何将字节数组插入到 bytea 类型的 postgresql 字段的示例。这是一个简单的练习。插入代码的示例如下所示:

insert into logos (id, bytes, type, created) values (?, ?, ?, now()) 

并且字节将设置为:

...
byte[] bytes = ... // read PNG file into a byte array.
...
ps.setBytes(2, bytes);
...

第二种方式在表格中插入行将来自纯文本文件脚本。需要这样做的原因只是为了将测试数据填充到表中以进行自动化测试,或者使用一些记录来初始化数据库以用于远程开发环境。

无论数据如何输入到表格中,应用程序显然需要能够从表格中选择 bytea 数据并将其转换回 PNG 图像。


问题

如何正确编码字节数组,以便能够从脚本中插入数据,从而只有文件中包含的原始字节存储在数据库中?

我可以编写代码来读取文件并输出插入语句来填充脚本。但我不知道如何对纯文本脚本的字节数组进行编码,这样当从 psql 运行脚本时,图像数据将与使用 setBytes jdbc 代码插入文件时相同。

我想用这样的方式运行脚本:

psql -U username -d dataBase -a -f test_data.sql

【问题讨论】:

    标签: postgresql character-encoding


    【解决方案1】:

    IMO,在 SQL 文件中表示 bytea 数据的最简单方法是使用 hex format

    8.4.1。 bytea 十六进制格式

    “十六进制”格式将二进制数据编码为每个字节 2 个十六进制数字,最重要的半字节在前。整个字符串前面是序列\x(以区别于转义格式)。在某些情况下,最初的反斜杠可能需要通过加倍来转义,在相同的情况下,反斜杠必须在转义格式中加倍;详情如下。十六进制数字可以是大写或小写,数字对之间允许有空格(但不能在数字对内,也不能在起始\x 序列中)。 hex 格式兼容多种外部应用程序和协议,而且转换速度往往比转义格式快,因此首选使用它。

    例子:

    SELECT E'\\xDEADBEEF';
    

    将字节数组转换为十六进制在任何一个理智的人(比如你自己)用来编写 SQL 文件生成器的语言中都应该是微不足道的。

    【讨论】:

    • 看起来这可能对我有用,但由于某种原因,当我从数据库中检索徽标时,字节数组的长度是应有的两倍。谷歌向我推荐了 bytea_output 参数,但我不知道如何将参数设置为十六进制。任何帮助表示赞赏。我是 postgresql 新手。
    • 您是在 Java/JDBC 中执行此操作吗?我不知道如何为此配置Java。 This thread 建议您可能需要更新版本的 JDBC 驱动程序。
    • 最终是的,但是代码确实是用 scala 和 anorm 编写的。该数据库是使用 puppet 脚本安装的。我认为数据库是 postgres 9.1,如 puppet 脚本中所指定,但 select version() 吐出“x86_64-redhat-linux-gnu 上的 PostgreSQL 8.4.18,由 GCC gcc (GCC) 4.4.7 20120313 (Red Hat 4.4. 7-3), 64-bit" 和 jdbc 驱动(gradle 坐标)是 postgresql:postgresql:9.1-901.jdbc4
    • 从 psql 连接会给出“警告:psql 版本 9.1,服务器版本 8.4。”
    • 您是否尝试过使用“转义”格式?该手册在我链接到的十六进制格式部分下方对其进行了描述。 AFAIK bytea 的默认格式在 PostgreSQL 9.0 左右从转义变为十六进制。
    猜你喜欢
    • 2011-08-25
    • 1970-01-01
    • 2014-07-27
    • 2013-01-25
    • 2015-09-13
    • 2021-11-16
    • 1970-01-01
    • 2013-08-07
    • 2019-09-12
    相关资源
    最近更新 更多