Skip to content

Commit 5d631a6

Browse files
committed
Using lookup() to determine true dataset instead of allocate_ids().
1 parent 0a1ffdf commit 5d631a6

File tree

2 files changed

+63
-15
lines changed

2 files changed

+63
-15
lines changed

gcloud/datastore/__init__.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,13 @@ def _find_true_dataset_id(dataset_id, connection=None):
7373
"""Find the true (unaliased) dataset ID.
7474
7575
If the given ID already has a 's~' or 'e~' prefix, does nothing.
76-
Otherwise, allocates a single key of bogus kind '__MissingLookupKind' and
77-
reads the true prefixed dataset ID from the response.
76+
Otherwise, looks up a bogus Key('__MissingLookupKind', 1) and reads the
77+
true prefixed dataset ID from the response (either from found or from
78+
missing).
79+
80+
For some context, see:
81+
github.com/GoogleCloudPlatform/gcloud-python/pull/528
82+
github.com/GoogleCloudPlatform/google-cloud-datastore/issues/59
7883
7984
:type dataset_id: string
8085
:param dataset_id: The dataset ID to un-alias / prefix.
@@ -90,15 +95,22 @@ def _find_true_dataset_id(dataset_id, connection=None):
9095

9196
connection = connection or _implicit_environ.CONNECTION
9297

93-
# Create the partial Key protobuf to be allocated and remove
98+
# Create the bogus Key protobuf to be looked up and remove
9499
# the dataset ID so the backend won't complain.
95-
bogus_key_pb = Key('__MissingLookupKind',
100+
bogus_key_pb = Key('__MissingLookupKind', 1,
96101
dataset_id=dataset_id).to_protobuf()
97102
bogus_key_pb.partition_id.ClearField('dataset_id')
98103

99-
allocated_pb, = connection.allocate_ids(dataset_id, [bogus_key_pb])
104+
missing_pbs = []
105+
found_pbs = connection.lookup(dataset_id, [bogus_key_pb],
106+
missing=missing_pbs)
107+
# By not passing in `deferred`, lookup will continue until
108+
# all results are `found` or `missing`.
109+
all_pbs = missing_pbs + found_pbs
110+
# We only asked for one, so should only receive one.
111+
returned_pb, = all_pbs
100112

101-
return allocated_pb.partition_id.dataset_id
113+
return returned_pb.key.partition_id.dataset_id
102114

103115

104116
def set_default_dataset_id(dataset_id=None):

gcloud/datastore/test___init__.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,46 @@ def test_unprefixed_no_connection(self):
9898
with self.assertRaises(AttributeError):
9999
self._callFUT(UNPREFIXED)
100100

101-
def test_unprefixed_explicit_connection(self):
101+
def test_unprefixed_bogus_key_miss(self):
102102
UNPREFIXED = 'DATASET'
103103
PREFIX = 's~'
104-
CONNECTION = _Connection(PREFIX)
104+
CONNECTION = _Connection(PREFIX, from_missing=False)
105105
result = self._callFUT(UNPREFIXED, connection=CONNECTION)
106106

107107
self.assertEqual(CONNECTION._called_dataset_id, UNPREFIXED)
108+
109+
self.assertEqual(len(CONNECTION._lookup_result), 1)
110+
self.assertEqual(CONNECTION._called_missing, [])
111+
112+
# Make sure just one.
113+
called_key_pb, = CONNECTION._called_key_pbs
114+
path_element = called_key_pb.path_element
115+
self.assertEqual(len(path_element), 1)
116+
self.assertEqual(path_element[0].kind, '__MissingLookupKind')
117+
self.assertEqual(path_element[0].id, 1)
118+
self.assertFalse(path_element[0].HasField('name'))
119+
120+
PREFIXED = PREFIX + UNPREFIXED
121+
self.assertEqual(result, PREFIXED)
122+
123+
def test_unprefixed_bogus_key_hit(self):
124+
UNPREFIXED = 'DATASET'
125+
PREFIX = 'e~'
126+
CONNECTION = _Connection(PREFIX, from_missing=True)
127+
result = self._callFUT(UNPREFIXED, connection=CONNECTION)
128+
129+
self.assertEqual(CONNECTION._called_dataset_id, UNPREFIXED)
130+
131+
self.assertEqual(CONNECTION._lookup_result, [])
132+
# Though missing=[] was called, it is copied in place.
133+
self.assertEqual(len(CONNECTION._called_missing), 1)
134+
108135
# Make sure just one.
109136
called_key_pb, = CONNECTION._called_key_pbs
110137
path_element = called_key_pb.path_element
111138
self.assertEqual(len(path_element), 1)
112139
self.assertEqual(path_element[0].kind, '__MissingLookupKind')
113-
self.assertFalse(path_element[0].HasField('id'))
140+
self.assertEqual(path_element[0].id, 1)
114141
self.assertFalse(path_element[0].HasField('name'))
115142

116143
PREFIXED = PREFIX + UNPREFIXED
@@ -207,19 +234,28 @@ def test_it(self):
207234

208235
class _Connection(object):
209236

210-
def __init__(self, prefix):
237+
def __init__(self, prefix, from_missing=False):
211238
self.prefix = prefix
239+
self.from_missing = from_missing
212240

213-
def allocate_ids(self, dataset_id, key_pbs):
241+
def lookup(self, dataset_id, key_pbs, missing=None):
214242
from gcloud.datastore import _datastore_v1_pb2 as datastore_pb
215243

216244
# Store the arguments called with.
217245
self._called_dataset_id = dataset_id
218246
self._called_key_pbs = key_pbs
247+
self._called_missing = missing
219248

220249
key_pb, = key_pbs
221250

222-
response = datastore_pb.Key()
223-
response.CopyFrom(key_pb)
224-
response.partition_id.dataset_id = self.prefix + dataset_id
225-
return [response]
251+
response = datastore_pb.Entity()
252+
response.key.CopyFrom(key_pb)
253+
response.key.partition_id.dataset_id = self.prefix + dataset_id
254+
255+
if self.from_missing:
256+
missing[:] = [response]
257+
self._lookup_result = []
258+
else:
259+
self._lookup_result = [response]
260+
261+
return self._lookup_result

0 commit comments

Comments
 (0)