通过LevelDB将协议缓冲区序列化数据从C ++传递到Python

时间:2012-01-28 13:33:09

标签: c++ serialization protocol-buffers key-value leveldb

虽然我已经遵循了优秀的协议缓冲区文档和C ++和Python教程,但我无法实现我的目标:      - 从C ++进程序列化数据。      - 从同一个进程将其插入LevelDB。      - 从Python进程中提取序列化数据      - 从同一个Python进程中去除它      - 在Python中使用那些deseralized数据

我可以使用C ++中的协议缓冲区序列化我的数据(使用std :: string容器)。我可以将它插入LevelDB。但是,当我在levelDB->获取我的序列化数据时,尽管Python似乎将它识别为String,并向我显示它们的原始内容,每当我将其反序列化为Python String时,它都是空的!

以下是我在C ++中序列化和插入数据的方法:

int                             main(int arg, char** argv)
 {
     GOOGLE_PROTOBUF_VERIFY_VERSION;

     leveldb::DB*                  db;
     leveldb::Options              options;
     leveldb::Status               status;
     tutorial::AddressBook         address_book;
     tutorial::Person*             person1;
     tutorial::Person*             person2;

     options.create_if_missing = true;
     status = leveldb::DB::Open(options, "test_db", &db);
     assert(status.ok());

     person1 = address_book.add_person();
     person1->set_id(1);
     person1->set_name("ME");
     person1->set_email("me@me.com");

     person2 = address_book.add_person();
     person2->set_id(2);
     person2->set_name("SHE");
     person2->set_email("she@she.com");

     std::string                   test;
     if (!address_book.SerializeToString(&test))
     {
         std::cerr << "Failed to write address book" << std::endl;
         return -1;
     }

     if (status.ok()) status = db->Put(leveldb::WriteOptions(), "Test", test);

以下是我尝试在Python中反序列化的方法:

address_book = addressbook_pb2.AddressBook()
db = leveldb.LevelDB('test_db')
ab = address_book.ParseFromString(db.Get("Test"))

ad var type是NoneType

编辑:     在db.Get()之前,ab.ByteSize()在ParseFromString()之后返回0,76,我认为它是Type问题然后......     +     ab.ListFields()返回包含字段的unexploitable列表:成功地couting两个人实例,但无法让我访问它。

任何线索,任何我不理解的想法,我在这里做错了什么?

非常感谢!

2 个答案:

答案 0 :(得分:1)

好的,所以这是我的坏事。

我回到了Protocol Buffers Python文档,事实是,即使我正在检索的AdressBook对象没有显示任何描述,它仍然可以迭代甚至有一个。 str < / strong>()方法。

所以,如果有人再次遇到这个问题,就像我一样尝试使用iPython探索你的ProtocolBuffers对象,你会发现你的每个proto元素都是你对象的字段。 用我的例子:

ab = adress_book.ParseFromString(db.Get('Test'))
ab.__str__()  # Shows a readable version of my object
for person in adress_book.person:  # I'm even able to iterate over any of my ab fields values
    print person.id
    print person.name

答案 1 :(得分:0)

尝试使用'代替"

ab = address_book.ParseFromString(db->Get('Test'))