如何使用 D 从 PostgreSQL load/unload 二进制 blob?

How to load/unload binary blob from PostgreSQL with D?

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

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

字段类型为:bytea

现在数据库像 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;

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

你可以看看DDBC是如何处理这些的。

我建议您 copy/paste 在您的项目文件之一中使用 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;
}

bytea encoding/decoding 函数有问题。 已在 ddbc v0.2.32

中修复