db.model_from_protobuf() equivalents outside of Ap

2019-07-25 08:50发布

问题:

In Google AppEngine(GAE) environment, I can do following to convert a Protobuf bytestring back to a Datastore model:

from google.appengine.ext import db

byte_str = ....
model = db.model_from_protobuf(byte_str.decode("base64"))

Outside of GAE, I normally use the google-cloud-datastore client to access Datastore models:

from google.cloud import datastore

...
client = datastore.Client(project_id)
query = client.query(kind='Event', order=('-date',))
for result in query.fetch(limit=100):
    print result

# every result is of class `google.cloud.datastore.entity.Entity`

Question: What if I'm only given the encoded byte string? How can I convert it back to a google.cloud.datastore.entity.Entity (or dict)?


Followups:

Update1: google.cloud.proto.datastore.v1.entity_pb2.Entity.ParseFromString() is the closest I found so far. But not quite working yet..

## fetched a protobuf into `pb`
>>> pb.__class__
<class 'google.cloud.proto.datastore.v1.entity_pb2.Entity'>

>>> entity = google.cloud.datastore.helpers.entity_from_protobuf(pb)
>>> entity.__class__
<class 'google.cloud.datastore.entity.Entity'>

>>> serialized = pb.SerializeToString()     ## <-- now this is the bytestring I meant.
>>> type(serialized)
<type 'str'>

>>> google.cloud.proto.datastore.v1.entity_pb2.Entity.ParseFromString(serialized)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'ParseFromString' requires a 'google.protobuf.pyext._message.CMessage' object but received a 'str'

>>>google.cloud.proto.datastore.v1.entity_pb2.Entity().ParseFromString(serialized)
76942    ## <--??

Update2:

Actually had to do this:

e = google.cloud.proto.datastore.v1.entity_pb2.Entity()
e.ParseFromString(byte_str)
print e

And that did it..

回答1:

this worked:

e = google.cloud.proto.datastore.v1.entity_pb2.Entity()
e.ParseFromString(byte_str)
print e