Skip to content

Commit 1b152ee

Browse files
committed
Removing Key.get() and Entity.reload().
Removed Entity.reload() because it relied on the existence of Key.get(). Replacing it would have required import gcloud.datastore.get in entity.py, which would have again been a cyclic import. With an eye on removing the Entity class (see #490), removing Entity.reload() is not such a big deal. Fixes #517.
1 parent 923302a commit 1b152ee

File tree

8 files changed

+29
-146
lines changed

8 files changed

+29
-146
lines changed

gcloud/datastore/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ def get_connection():
107107
>>> connection = datastore.get_connection()
108108
>>> key1 = Key('Kind', 1234, dataset_id='dataset1')
109109
>>> key2 = Key('Kind', 1234, dataset_id='dataset2')
110-
>>> entity1 = key1.get(connection=connection)
111-
>>> entity2 = key2.get(connection=connection)
110+
>>> entity1 = datastore.get(key1, connection=connection)
111+
>>> entity2 = datastore.get(key2, connection=connection)
112112
113113
:rtype: :class:`gcloud.datastore.connection.Connection`
114114
:returns: A connection defined with the proper credentials.

gcloud/datastore/connection.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,13 @@ def lookup(self, dataset_id, key_pbs,
166166
This method deals only with protobufs
167167
(:class:`gcloud.datastore.datastore_v1_pb2.Key` and
168168
:class:`gcloud.datastore.datastore_v1_pb2.Entity`) and is used
169-
under the hood for methods like
170-
:meth:`gcloud.datastore.key.Key.get`:
169+
under the hood in :func:`gcloud.datastore.get`:
171170
172171
>>> from gcloud import datastore
173172
>>> from gcloud.datastore.key import Key
174173
>>> datastore.set_default_connection()
175174
>>> key = Key('MyKind', 1234, dataset_id='dataset-id')
176-
>>> key.get()
175+
>>> datastore.get(key)
177176
<Entity object>
178177
179178
Using the ``connection`` class directly:

gcloud/datastore/entity.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ class Entity(dict):
4040
This means you could take an existing entity and change the key
4141
to duplicate the object.
4242
43-
Use :meth:`gcloud.datastore.key.Key.get` to retrieve an existing entity.
43+
Use :func:`gcloud.datastore.get` to retrieve an existing entity.
4444
45-
>>> key.get()
45+
>>> datastore.get(key)
4646
<Entity[{'kind': 'EntityKind', id: 1234}] {'property': 'value'}>
4747
4848
You can the set values on the entity just like you would on any
@@ -116,29 +116,6 @@ def _must_key(self):
116116
raise NoKey()
117117
return self.key
118118

119-
def reload(self, connection=None):
120-
"""Reloads the contents of this entity from the datastore.
121-
122-
This method takes the :class:`gcloud.datastore.key.Key`, loads all
123-
properties from the Cloud Datastore, and sets the updated properties on
124-
the current object.
125-
126-
.. warning::
127-
This will override any existing properties if a different value
128-
exists remotely, however it will *not* override any properties that
129-
exist only locally.
130-
131-
:type connection: :class:`gcloud.datastore.connection.Connection`
132-
:param connection: Optional connection used to connect to datastore.
133-
"""
134-
connection = connection or _implicit_environ.CONNECTION
135-
136-
key = self._must_key
137-
entity = key.get(connection=connection)
138-
139-
if entity:
140-
self.update(entity)
141-
142119
def save(self, connection=None):
143120
"""Save the entity in the Cloud Datastore.
144121

gcloud/datastore/key.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -217,29 +217,6 @@ def to_protobuf(self):
217217

218218
return key
219219

220-
def get(self, connection=None):
221-
"""Retrieve entity corresponding to the current key.
222-
223-
:type connection: :class:`gcloud.datastore.connection.Connection`
224-
:param connection: Optional connection used to connect to datastore.
225-
226-
:rtype: :class:`gcloud.datastore.entity.Entity` or :class:`NoneType`
227-
:returns: The requested entity, or ``None`` if there was no
228-
match found.
229-
"""
230-
# Temporary cylic import, needs to be removed.
231-
from gcloud.datastore import api
232-
233-
# We allow partial keys to attempt a get, the backend will fail.
234-
connection = connection or _implicit_environ.CONNECTION
235-
entities = api.get([self], connection=connection)
236-
237-
if entities:
238-
result = entities[0]
239-
# We assume that the backend has not changed the key.
240-
result.key = self
241-
return result
242-
243220
def delete(self, connection=None):
244221
"""Delete the key in the Cloud Datastore.
245222

gcloud/datastore/test_entity.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,6 @@ def test__must_key_no_key(self):
5959
entity = self._makeOne()
6060
self.assertRaises(NoKey, getattr, entity, '_must_key')
6161

62-
def test_reload_no_key(self):
63-
from gcloud.datastore.entity import NoKey
64-
65-
entity = self._makeOne()
66-
entity['foo'] = 'Foo'
67-
self.assertRaises(NoKey, entity.reload)
68-
69-
def test_reload_miss(self):
70-
key = _Key()
71-
key._stored = None # Explicit miss.
72-
entity = self._makeOne(key=key)
73-
entity['foo'] = 'Foo'
74-
# Does not raise, does not update on miss.
75-
entity.reload()
76-
self.assertEqual(entity['foo'], 'Foo')
77-
78-
def test_reload_hit(self):
79-
key = _Key()
80-
NEW_VAL = 'Baz'
81-
key._stored = {'foo': NEW_VAL}
82-
entity = self._makeOne(key=key)
83-
entity['foo'] = 'Foo'
84-
entity.reload()
85-
self.assertEqual(entity['foo'], NEW_VAL)
86-
self.assertEqual(entity.keys(), ['foo'])
87-
8862
def test_save_no_key(self):
8963
from gcloud.datastore.entity import NoKey
9064

@@ -186,10 +160,6 @@ def is_partial(self):
186160
def path(self):
187161
return self._path
188162

189-
def get(self, connection=None):
190-
self._connection_used = connection
191-
return self._stored
192-
193163

194164
class _Connection(object):
195165
_transaction = _saved = _deleted = None

gcloud/datastore/test_key.py

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -232,62 +232,6 @@ def test_to_protobuf_w_no_kind(self):
232232
pb = key.to_protobuf()
233233
self.assertFalse(pb.path_element[0].HasField('kind'))
234234

235-
def test_get_explicit_connection_miss(self):
236-
from gcloud.datastore.test_connection import _Connection
237-
238-
cnxn_lookup_result = []
239-
cnxn = _Connection(*cnxn_lookup_result)
240-
key = self._makeOne('KIND', 1234, dataset_id=self._DEFAULT_DATASET)
241-
entity = key.get(connection=cnxn)
242-
self.assertEqual(entity, None)
243-
244-
def test_get_implicit_connection_miss(self):
245-
from gcloud._testing import _Monkey
246-
from gcloud.datastore import _implicit_environ
247-
from gcloud.datastore.test_connection import _Connection
248-
249-
cnxn_lookup_result = []
250-
cnxn = _Connection(*cnxn_lookup_result)
251-
key = self._makeOne('KIND', 1234, dataset_id=self._DEFAULT_DATASET)
252-
with _Monkey(_implicit_environ, CONNECTION=cnxn):
253-
entity = key.get()
254-
self.assertEqual(entity, None)
255-
256-
def test_get_explicit_connection_hit(self):
257-
from gcloud.datastore import datastore_v1_pb2
258-
from gcloud.datastore.test_connection import _Connection
259-
260-
KIND = 'KIND'
261-
ID = 1234
262-
263-
# Make a bogus entity PB to be returned from fake Connection.
264-
entity_pb = datastore_v1_pb2.Entity()
265-
entity_pb.key.partition_id.dataset_id = self._DEFAULT_DATASET
266-
path_element = entity_pb.key.path_element.add()
267-
path_element.kind = KIND
268-
path_element.id = ID
269-
prop = entity_pb.property.add()
270-
prop.name = 'foo'
271-
prop.value.string_value = 'Foo'
272-
273-
# Make fake connection.
274-
cnxn_lookup_result = [entity_pb]
275-
cnxn = _Connection(*cnxn_lookup_result)
276-
277-
# Create key and look-up.
278-
key = self._makeOne(KIND, ID, dataset_id=self._DEFAULT_DATASET)
279-
entity = key.get(connection=cnxn)
280-
self.assertEqual(entity.items(), [('foo', 'Foo')])
281-
self.assertTrue(entity.key is key)
282-
283-
def test_get_no_connection(self):
284-
from gcloud.datastore import _implicit_environ
285-
286-
self.assertEqual(_implicit_environ.CONNECTION, None)
287-
key = self._makeOne('KIND', 1234, dataset_id=self._DEFAULT_DATASET)
288-
with self.assertRaises(EnvironmentError):
289-
key.get()
290-
291235
def test_delete_explicit_connection(self):
292236
from gcloud.datastore.test_connection import _Connection
293237

pylintrc_default

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,13 @@ ignore =
7373
# identical implementation but different docstrings.
7474
# - star-args: standard Python idioms for varargs:
7575
# ancestor = Query().filter(*order_props)
76-
# - cyclic-import: temporary workaround to support Key.get until Dataset
77-
# is removed in #477.
7876
disable =
7977
maybe-no-member,
8078
no-member,
8179
protected-access,
8280
redefined-builtin,
8381
similarities,
8482
star-args,
85-
cyclic-import,
8683

8784

8885
[REPORTS]

regression/datastore.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,12 @@ def _generic_test_post(self, name=None, key_id=None):
9191
self.assertEqual(entity.key.name, name)
9292
if key_id is not None:
9393
self.assertEqual(entity.key.id, key_id)
94-
retrieved_entity = entity.key.get()
94+
retrieved_entity = datastore.get(entity.key)
9595
# Check the keys are the same.
96-
self.assertTrue(retrieved_entity.key is entity.key)
96+
self.assertEqual(retrieved_entity.key.path, entity.key.path)
97+
self.assertEqual(retrieved_entity.key.namespace, entity.key.namespace)
98+
self.assertTrue(_compare_dataset_ids(
99+
retrieved_entity.key.dataset_id, entity.key.dataset_id))
97100

98101
# Check the data is the same.
99102
retrieved_dict = dict(retrieved_entity.items())
@@ -343,14 +346,30 @@ def test_transaction(self):
343346
entity['url'] = u'www.google.com'
344347

345348
with Transaction():
346-
retrieved_entity = entity.key.get()
349+
retrieved_entity = datastore.get(entity.key)
347350
if retrieved_entity is None:
348351
entity.save()
349352
self.case_entities_to_delete.append(entity)
350353

351354
# This will always return after the transaction.
352-
retrieved_entity = entity.key.get()
355+
retrieved_entity = datastore.get(entity.key)
353356
self.case_entities_to_delete.append(retrieved_entity)
354357
retrieved_dict = dict(retrieved_entity.items())
355358
entity_dict = dict(entity.items())
356359
self.assertEqual(retrieved_dict, entity_dict)
360+
361+
362+
def _compare_dataset_ids(dataset_id1, dataset_id2):
363+
if dataset_id1 == dataset_id2:
364+
return True
365+
366+
if dataset_id1.startswith('s~') or dataset_id1.startswith('e~'):
367+
# If `dataset_id1` is prefixed and not matching, then the only way
368+
# they can match is if `dataset_id2` is unprefixed.
369+
return dataset_id1[2:] == dataset_id2
370+
elif dataset_id2.startswith('s~') or dataset_id2.startswith('e~'):
371+
# Here we know `dataset_id1` is unprefixed and `dataset_id2`
372+
# is prefixed.
373+
return dataset_id1 == dataset_id2[2:]
374+
375+
return False

0 commit comments

Comments
 (0)