Skip to content

Commit ab4c103

Browse files
committed
Using lookup() to determine true dataset instead of allocate_ids().
1 parent 6f1819f commit ab4c103

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
@@ -72,8 +72,13 @@ def _find_true_dataset_id(dataset_id, connection=None):
7272
"""Find the true (unaliased) dataset ID.
7373
7474
If the given ID already has a 's~' or 'e~' prefix, does nothing.
75-
Otherwise, allocates a single key of bogus kind '__Foo' and reads
76-
the true prefixed dataset ID from the response.
75+
Otherwise, looks up a bogus Key('__Foo', 1) and reads the true
76+
prefixed dataset ID from the response (either from found or from
77+
missing).
78+
79+
For some context, see:
80+
github.com/GoogleCloudPlatform/gcloud-python/pull/528
81+
github.com/GoogleCloudPlatform/google-cloud-datastore/issues/59
7782
7883
:type dataset_id: string
7984
:param dataset_id: The dataset ID to un-alias / prefix.
@@ -89,14 +94,21 @@ def _find_true_dataset_id(dataset_id, connection=None):
8994

9095
connection = connection or _implicit_environ.CONNECTION
9196

92-
# Create the partial Key protobuf to be allocated and remove
97+
# Create the bogus Key protobuf to be looked up and remove
9398
# the dataset ID so the backend won't complain.
94-
bogus_key_pb = Key('__Foo', dataset_id=dataset_id).to_protobuf()
99+
bogus_key_pb = Key('__Foo', 1, dataset_id=dataset_id).to_protobuf()
95100
bogus_key_pb.partition_id.ClearField('dataset_id')
96101

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

99-
return allocated_pb.partition_id.dataset_id
111+
return returned_pb.key.partition_id.dataset_id
100112

101113

102114
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, '__Foo')
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, '__Foo')
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)