简体   繁体   English

使用 pqxx 从 postgres 读取/写入大对象

[英]Read/write large object from postgres using pqxx

The main pqxx API works with columns as text.主要的 pqxx API 以文本形式处理列。 So how to access binary data from large objects (LOB) using the pqxx library?那么如何使用 pqxx 库从大对象 (LOB) 访问二进制数据呢?

There are a couple of ways.有几种方法。 The first way, is to translate the data to/from bytea, and work through the common pqxx api.第一种方法是将数据与 bytea 相互转换,并通过通用的 pqxx api 工作。 If you know how to work with bytea, probably this is your way.如果您知道如何使用 bytea,那么这可能就是您的方式。 Here is example how to insert a string as lob, plain sql, no c++ code:以下是如何将字符串插入为 lob、纯 sql、无 C++ 代码的示例:

select lo_from_bytea(0, 'this is a test'::bytea);
...
select encode(lo_get(190850), 'escape'); -- here 190850 is the oid for lob created by the first line.

The other option is to use iostream API provided by pqxx library.另一种选择是使用 pqxx 库提供的 iostream API。 There is no much examples of how to use it, so here we go:没有太多关于如何使用它的例子,所以我们开始:

// write lob
auto conn = std::make_shared<pqxx::connection>(url);
auto tran = std::make_shared<pqxx::work>(*conn);
auto stream = std::make_shared<pqxx::olostream>(*tran, oid);
stream->write(data, size);
stream->flush();
stream.reset();
tran->commit();

// read lob
stream = std::make_shared<pqxx::ilostream>(*tran, oid);
...
sszie_t get_chunk(shard_ptr<> stream, char *buf, size_t max_len)
{
    while (!stream->eof() && len < max_len && stream->get(buf[len])) {
        len++;
    }

    return (len > 0 || !stream->eof()) ? len : -1;
}

Note: there is a bug in pqxx::ilostream, you can get truncated data if 0xff byte in the data will hit the inner buffer boundary, it will mistakenly considered as EOF character.注意:pqxx::ilostream 有一个bug,如果数据中的0xff 字节碰到内部缓冲区边界,你会得到截断的数据,它会被误认为是EOF 字符。 The bug was fixed in the february 2020, and for now this fix didn't get to all distributions.该错误已于 2020 年 2 月修复,目前此修复并未适用于所有发行版。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM