For example if a query is passes q.ancestor(None) the returned object is a clone with the ancestor removed (i.e. literally set the ancestor to None). This behavior is not mentioned in the docstring and should be added.
In order to actually access the ancestor, a user needs to parse it from the query's protobuf:
>>> from gcloud import datastore
>>> from gcloud.datastore import datastore_v1_pb2 as datastore_pb
>>> ANCESTOR = {'kind': 'Book', 'name': 'GoT'}
>>> ANCESTOR_KEY = datastore.key.Key(path=[ANCESTOR])
>>> dataset = datastore.dataset.Dataset('foo')
>>> q = dataset.query('Character').ancestor(ANCESTOR_KEY)
>>> ancestor_filters = {
... i: filter_obj
... for i, filter_obj in enumerate(q._pb.filter.composite_filter.filter)
... if (filter_obj.property_filter.operator ==
... datastore_pb.PropertyFilter.HAS_ANCESTOR)
... }
>>> # for key in ancestor_filters.keys():
... # del q._pb.filter.composite_filter.filter[key]
... # # If q has no more filters...
... # if not q._pb.filter.composite_filter.filter:
... # q._pb.ClearField('filter')
... _, filter_obj = ancestor_filters.popitem()
>>> ancestor_filter = filter_obj.property_filter
>>> ancestor_filter.property.name
u'__key__'
>>> ancestor_filter.operator == datastore_pb.PropertyFilter.HAS_ANCESTOR
True
>>> key_pb = ancestor_filter.value.key_value
>>> key_pb
<gcloud.datastore.datastore_v1_pb2.Key object at 0x7f069f2372a8>
>>> key = datastore.helpers.key_from_protobuf(key_pb)
>>> key
<Key[{'kind': u'Book', 'name': u'GoT'}]>
>>> ANCESTOR_KEY
<Key[{'kind': 'Book', 'name': 'GoT'}]>
For example if a query is passes
q.ancestor(None)the returned object is a clone with the ancestor removed (i.e. literally set the ancestor toNone). This behavior is not mentioned in the docstring and should be added.In order to actually access the
ancestor, a user needs to parse it from the query's protobuf: