Skip to content

Commit daaa26e

Browse files
committed
Removing dataset_id from get_entities.
It can be implied from the keys passed in.
1 parent 75d22ad commit daaa26e

File tree

3 files changed

+72
-22
lines changed

3 files changed

+72
-22
lines changed

gcloud/datastore/__init__.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ def _require_connection(connection=None):
153153
return connection
154154

155155

156-
def get_entities(keys, missing=None, deferred=None,
157-
connection=None, dataset_id=None):
156+
def get_entities(keys, missing=None, deferred=None, connection=None):
158157
"""Retrieves entities, along with their attributes.
159158
160159
:type keys: list of :class:`gcloud.datastore.key.Key`
@@ -173,14 +172,23 @@ def get_entities(keys, missing=None, deferred=None,
173172
:type connection: :class:`gcloud.datastore.connection.Connection`
174173
:param connection: Optional. The connection used to connect to datastore.
175174
176-
:type dataset_id: string
177-
:param dataset_id: Optional. The ID of the dataset.
178-
179175
:rtype: list of :class:`gcloud.datastore.entity.Entity`
180176
:returns: The requested entities.
177+
:raises: :class:`ValueError` if the key dataset IDs don't agree.
181178
"""
179+
if not keys:
180+
return []
181+
182182
connection = _require_connection(connection)
183-
dataset_id = _require_dataset_id(dataset_id)
183+
dataset_id = keys[0].dataset_id
184+
# Rather than creating a list or set of all dataset IDs, we iterate
185+
# and check. We could allow the backend to check this for us if IDs
186+
# with no prefix worked (GoogleCloudPlatform/google-cloud-datastore#59)
187+
# or if we made sure that a prefix s~ or e~ was on each key.
188+
for key in keys[1:]:
189+
if key.dataset_id != dataset_id:
190+
raise ValueError('All keys in get_entities must be from the '
191+
'same dataset.')
184192

185193
entity_pbs = connection.lookup(
186194
dataset_id=dataset_id,

gcloud/datastore/key.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,7 @@ def get(self, connection=None):
232232

233233
# We allow partial keys to attempt a get, the backend will fail.
234234
connection = connection or _implicit_environ.CONNECTION
235-
entities = datastore.get_entities(
236-
[self], connection=connection, dataset_id=self.dataset_id)
235+
entities = datastore.get_entities([self], connection=connection)
237236

238237
if entities:
239238
result = entities[0]

gcloud/datastore/test___init__.py

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,14 @@ def test__require_connection_implicit_set_passed_explicitly(self):
213213

214214
class Test_get_entities_function(unittest2.TestCase):
215215

216-
def _callFUT(self, keys, missing=None, deferred=None,
217-
connection=None, dataset_id=None):
216+
def _callFUT(self, keys, missing=None, deferred=None, connection=None):
218217
from gcloud.datastore import get_entities
219218
return get_entities(keys, missing=missing, deferred=deferred,
220-
connection=connection, dataset_id=dataset_id)
219+
connection=connection)
220+
221+
def test_get_entities_no_keys(self):
222+
results = self._callFUT([])
223+
self.assertEqual(results, [])
221224

222225
def test_get_entities_miss(self):
223226
from gcloud.datastore.key import Key
@@ -226,8 +229,7 @@ def test_get_entities_miss(self):
226229
DATASET_ID = 'DATASET'
227230
connection = _Connection()
228231
key = Key('Kind', 1234, dataset_id=DATASET_ID)
229-
results = self._callFUT([key], connection=connection,
230-
dataset_id=DATASET_ID)
232+
results = self._callFUT([key], connection=connection)
231233
self.assertEqual(results, [])
232234

233235
def test_get_entities_miss_w_missing(self):
@@ -252,8 +254,7 @@ def test_get_entities_miss_w_missing(self):
252254

253255
key = Key(KIND, ID, dataset_id=DATASET_ID)
254256
missing = []
255-
entities = self._callFUT([key], connection=connection,
256-
dataset_id=DATASET_ID, missing=missing)
257+
entities = self._callFUT([key], connection=connection, missing=missing)
257258
self.assertEqual(entities, [])
258259
self.assertEqual([missed.key.to_protobuf() for missed in missing],
259260
[key.to_protobuf()])
@@ -271,22 +272,24 @@ def test_get_entities_miss_w_deferred(self):
271272

272273
deferred = []
273274
entities = self._callFUT([key], connection=connection,
274-
dataset_id=DATASET_ID, deferred=deferred)
275+
deferred=deferred)
275276
self.assertEqual(entities, [])
276277
self.assertEqual([def_key.to_protobuf() for def_key in deferred],
277278
[key.to_protobuf()])
278279

279-
def _make_entity_pb(self, dataset_id, kind, integer_id, name, str_val):
280+
def _make_entity_pb(self, dataset_id, kind, integer_id,
281+
name=None, str_val=None):
280282
from gcloud.datastore import datastore_v1_pb2 as datastore_pb
281283

282284
entity_pb = datastore_pb.Entity()
283285
entity_pb.key.partition_id.dataset_id = dataset_id
284286
path_element = entity_pb.key.path_element.add()
285287
path_element.kind = kind
286288
path_element.id = integer_id
287-
prop = entity_pb.property.add()
288-
prop.name = name
289-
prop.value.string_value = str_val
289+
if name is not None and str_val is not None:
290+
prop = entity_pb.property.add()
291+
prop.name = name
292+
prop.value.string_value = str_val
290293

291294
return entity_pb
292295

@@ -307,8 +310,7 @@ def test_get_entities_hit(self):
307310
connection = _Connection(entity_pb)
308311

309312
key = Key(KIND, ID, dataset_id=DATASET_ID)
310-
result, = self._callFUT([key], connection=connection,
311-
dataset_id=DATASET_ID)
313+
result, = self._callFUT([key], connection=connection)
312314
new_key = result.key
313315

314316
# Check the returned value is as expected.
@@ -318,6 +320,47 @@ def test_get_entities_hit(self):
318320
self.assertEqual(list(result), ['foo'])
319321
self.assertEqual(result['foo'], 'Foo')
320322

323+
def test_get_entities_hit_multiple_keys_same_dataset(self):
324+
from gcloud.datastore.key import Key
325+
from gcloud.datastore.test_connection import _Connection
326+
327+
DATASET_ID = 'DATASET'
328+
KIND = 'Kind'
329+
ID1 = 1234
330+
ID2 = 2345
331+
332+
# Make a found entity pb to be returned from mock backend.
333+
entity_pb1 = self._make_entity_pb(DATASET_ID, KIND, ID1)
334+
entity_pb2 = self._make_entity_pb(DATASET_ID, KIND, ID2)
335+
336+
# Make a connection to return the entity pbs.
337+
connection = _Connection(entity_pb1, entity_pb2)
338+
339+
key1 = Key(KIND, ID1, dataset_id=DATASET_ID)
340+
key2 = Key(KIND, ID2, dataset_id=DATASET_ID)
341+
retrieved1, retrieved2 = self._callFUT(
342+
[key1, key2], connection=connection)
343+
344+
# Check values match.
345+
self.assertEqual(retrieved1.key.path, key1.path)
346+
self.assertEqual(dict(retrieved1), {})
347+
self.assertEqual(retrieved2.key.path, key2.path)
348+
self.assertEqual(dict(retrieved2), {})
349+
350+
def test_get_entities_hit_multiple_keys_different_dataset(self):
351+
from gcloud.datastore.key import Key
352+
353+
DATASET_ID1 = 'DATASET'
354+
DATASET_ID2 = 'DATASET-ALT'
355+
356+
# Make sure our IDs are actually different.
357+
self.assertNotEqual(DATASET_ID1, DATASET_ID2)
358+
359+
key1 = Key('KIND', 1234, dataset_id=DATASET_ID1)
360+
key2 = Key('KIND', 1234, dataset_id=DATASET_ID2)
361+
with self.assertRaises(ValueError):
362+
self._callFUT([key1, key2], connection=object())
363+
321364
def test_get_entities_implicit(self):
322365
from gcloud.datastore import _implicit_environ
323366
from gcloud.datastore.key import Key

0 commit comments

Comments
 (0)