如何使用D从PostgreSQL加载/卸载二进制blob?

时间:2016-04-07 07:39:58

标签: postgresql blob d

我使用下一个命令在PostgreSQL中加载图像:

UPDATE "USERS" SET userblob = (pg_read_binary_file('img.png')::bytea) WHERE id>1;

字段类型为:bytea

现在DB就像this

然后我尝试将二进制blob写回文件系统。并获得了包含以下数据的非常大的文件:[56, 57, 53, 48, 52, 101, 52, 55, 48, 100, 48, 97, 49 ...

我做错了什么?我的代码是下一个:

struct MyData
{
    string  guid;
    string  id;
    string  name;
    byte [] userblob;
    string  fl;
}   
        auto rs = pgstmt.executeQuery(`SELECT guid::text, id, name, userblob, "FL" FROM "USERS" where "FL" = 10;`);
    while (rs.next())
    {
        md.guid = to!string(rs.getString(1));
        md.id = to!string(rs.getString(2));
        md.name = to!string(rs.getString(3));
        md.userblob = rs.getBytes(4);
        md.fl = to!string(rs.getBytes(5));

        std.file.write("output.png", cast(byte[])md.userblob);
        readln;

        mydata ~= md;
    }
UPD:我读过文档。 PostgreSQL bytea很痛苦。将所有文本存储在base64编码中要好得多。 工作范例: UPDATE "USERS" SET userblob = encode(pg_read_binary_file('img.png'), 'base64') WHERE id>1;

2 个答案:

答案 0 :(得分:1)

bytea编码/解码功能存在问题。 已在ddbc v0.2.32中修复

答案 1 :(得分:0)

Postgres bytea似乎是问题的根源。从我在Postgres文档中可以看到的内容,bytea将存储字节流的不可打印值作为该值的八进制值的字符串表示。 这将需要一些处理才能获得实际的二进制流...

您可以查看DDBC如何处理这些内容。

我建议您将byte[] byteaToBytes(string s)函数复制/粘贴到某个项目文件中,并按如下方式调整代码:

while (rs.next())
{
    ...
    md.userblob = byteaToBytes(to!string(rs.getString(4)));
    ...
    std.file.write("output.png", cast(byte[])md.userblob);
    readln;

    mydata ~= md;
}