Skip to content

Commit 184cfb9

Browse files
committed
Allowing get() to accept a single key (in addition to list).
1 parent ea03dec commit 184cfb9

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

gcloud/datastore/api.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
Query objects rather than via protobufs.
1919
"""
2020

21+
import collections
22+
2123
from gcloud.datastore import _implicit_environ
2224
from gcloud.datastore import helpers
2325

@@ -58,11 +60,12 @@ def _require_connection(connection=None):
5860
return connection
5961

6062

61-
def get(keys, missing=None, deferred=None, connection=None):
63+
def get(key_or_keys, missing=None, deferred=None, connection=None):
6264
"""Retrieves entities, along with their attributes.
6365
64-
:type keys: list of :class:`gcloud.datastore.key.Key`
65-
:param keys: The name of the item to retrieve.
66+
:type key_or_keys: list of :class:`gcloud.datastore.key.Key` or single
67+
:class:`gcloud.datastore.key.Key`
68+
:param key_or_keys: The key or keys to be retrieved from the datastore.
6669
6770
:type missing: an empty list or None.
6871
:param missing: If a list is passed, the key-only entities returned
@@ -77,10 +80,15 @@ def get(keys, missing=None, deferred=None, connection=None):
7780
:type connection: :class:`gcloud.datastore.connection.Connection`
7881
:param connection: Optional. The connection used to connect to datastore.
7982
80-
:rtype: list of :class:`gcloud.datastore.entity.Entity`
81-
:returns: The requested entities.
82-
:raises: :class:`ValueError` if the key dataset IDs don't agree.
83+
:rtype: list of :class:`gcloud.datastore.entity.Entity`, single
84+
:class:`gcloud.datastore.entity.Entity`, or ``NoneType``
85+
:returns: The requested entities, or single entity.
8386
"""
87+
if isinstance(key_or_keys, collections.Iterable):
88+
keys = key_or_keys
89+
else:
90+
keys = [key_or_keys]
91+
8492
if not keys:
8593
return []
8694

@@ -114,7 +122,11 @@ def get(keys, missing=None, deferred=None, connection=None):
114122
for entity_pb in entity_pbs:
115123
entities.append(helpers.entity_from_protobuf(entity_pb))
116124

117-
return entities
125+
if keys is key_or_keys:
126+
return entities
127+
else:
128+
if entities:
129+
return entities[0]
118130

119131

120132
def allocate_ids(incomplete_key, num_ids, connection=None):

gcloud/datastore/test_api.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,23 @@ def test_get_no_keys(self):
101101
results = self._callFUT([])
102102
self.assertEqual(results, [])
103103

104-
def test_get_miss(self):
104+
def _miss_helper(self, expected_results, use_list=True):
105105
from gcloud.datastore.key import Key
106106
from gcloud.datastore.test_connection import _Connection
107107

108108
DATASET_ID = 'DATASET'
109109
connection = _Connection()
110110
key = Key('Kind', 1234, dataset_id=DATASET_ID)
111-
results = self._callFUT([key], connection=connection)
112-
self.assertEqual(results, [])
111+
if use_list:
112+
key = [key]
113+
results = self._callFUT(key, connection=connection)
114+
self.assertEqual(results, expected_results)
115+
116+
def test_get_miss(self):
117+
self._miss_helper([], use_list=True)
118+
119+
def test_get_miss_single_key(self):
120+
self._miss_helper(None, use_list=False)
113121

114122
def test_get_miss_w_missing(self):
115123
from gcloud.datastore import datastore_v1_pb2 as datastore_pb
@@ -240,6 +248,33 @@ def test_get_hit_multiple_keys_different_dataset(self):
240248
with self.assertRaises(ValueError):
241249
self._callFUT([key1, key2], connection=object())
242250

251+
def test_get_hit_single_key(self):
252+
from gcloud.datastore.key import Key
253+
from gcloud.datastore.test_connection import _Connection
254+
255+
DATASET_ID = 'DATASET'
256+
KIND = 'Kind'
257+
ID = 1234
258+
PATH = [{'kind': KIND, 'id': ID}]
259+
260+
# Make a found entity pb to be returned from mock backend.
261+
entity_pb = self._make_entity_pb(DATASET_ID, KIND, ID,
262+
'foo', 'Foo')
263+
264+
# Make a connection to return the entity pb.
265+
connection = _Connection(entity_pb)
266+
267+
key = Key(KIND, ID, dataset_id=DATASET_ID)
268+
result = self._callFUT(key, connection=connection)
269+
new_key = result.key
270+
271+
# Check the returned value is as expected.
272+
self.assertFalse(new_key is key)
273+
self.assertEqual(new_key.dataset_id, DATASET_ID)
274+
self.assertEqual(new_key.path, PATH)
275+
self.assertEqual(list(result), ['foo'])
276+
self.assertEqual(result['foo'], 'Foo')
277+
243278
def test_get_implicit(self):
244279
from gcloud.datastore import _implicit_environ
245280
from gcloud.datastore.key import Key

0 commit comments

Comments
 (0)