1919from gcloud .datastore .key import Key
2020
2121
22+ class NoKey (RuntimeError ):
23+ """Exception raised by Entity methods which require a key."""
24+
25+
2226class Entity (dict ): # pylint: disable=too-many-public-methods
2327 """:type dataset: :class:`gcloud.datastore.dataset.Dataset`
2428 :param dataset: The dataset in which this entity belongs.
@@ -82,8 +86,8 @@ def dataset(self):
8286 be `None`. It also means that if you change the key on the entity,
8387 this will refer to that key's dataset.
8488 """
85- if self .key () :
86- return self .key () .dataset ()
89+ if self ._key :
90+ return self ._key .dataset ()
8791
8892 def key (self , key = None ):
8993 """Get or set the :class:`.datastore.key.Key` on the current entity.
@@ -117,8 +121,8 @@ def kind(self):
117121 which knows its Kind.
118122 """
119123
120- if self .key () :
121- return self .key () .kind ()
124+ if self ._key :
125+ return self ._key .kind ()
122126
123127 @classmethod
124128 def from_key (cls , key ):
@@ -162,6 +166,18 @@ def from_protobuf(cls, pb, dataset=None): # pylint: disable=invalid-name
162166
163167 return entity
164168
169+ @property
170+ def _must_key (self ):
171+ """Return our key, or raise NoKey if not set.
172+
173+ :rtype: :class:`gcloud.datastore.key.Key`.
174+ :returns: our key
175+ :raises: NoKey if key is None
176+ """
177+ if self ._key is None :
178+ raise NoKey ('no key' )
179+ return self ._key
180+
165181 def reload (self ):
166182 """Reloads the contents of this entity from the datastore.
167183
@@ -174,11 +190,8 @@ def reload(self):
174190 exists remotely, however it will *not* override any properties that
175191 exist only locally.
176192 """
177-
178- # Note that you must have a valid key, otherwise this makes no sense.
179- # pylint: disable=maybe-no-member
180- entity = self .dataset ().get_entity (self .key ().to_protobuf ())
181- # pylint: enable=maybe-no-member
193+ key = self ._must_key
194+ entity = key .dataset ().get_entity (key .to_protobuf ())
182195
183196 if entity :
184197 self .update (entity )
@@ -196,27 +209,24 @@ def save(self):
196209 :rtype: :class:`gcloud.datastore.entity.Entity`
197210 :returns: The entity with a possibly updated Key.
198211 """
199- # pylint: disable=maybe-no-member
200- key_pb = self .dataset ().connection ().save_entity (
201- dataset_id = self .dataset ().id (),
202- key_pb = self .key ().to_protobuf (), properties = dict (self ))
203- # pylint: enable=maybe-no-member
212+ key = self ._must_key
213+ dataset = key .dataset ()
214+ connection = dataset .connection ()
215+ key_pb = connection .save_entity (
216+ dataset_id = dataset .id (),
217+ key_pb = key .to_protobuf (),
218+ properties = dict (self ))
204219
205220 # If we are in a transaction and the current entity needs an
206221 # automatically assigned ID, tell the transaction where to put that.
207- transaction = self .dataset ().connection ().transaction ()
208- # pylint: disable=maybe-no-member
209- if transaction and self .key ().is_partial ():
222+ transaction = connection .transaction ()
223+ if transaction and key .is_partial ():
210224 transaction .add_auto_id_entity (self )
211- # pylint: enable=maybe-no-member
212225
213226 if isinstance (key_pb , datastore_pb .Key ):
214227 updated_key = Key .from_protobuf (key_pb )
215228 # Update the path (which may have been altered).
216- # pylint: disable=maybe-no-member
217- key = self .key ().path (updated_key .path ())
218- # pylint: enable=maybe-no-member
219- self .key (key )
229+ self ._key = key .path (updated_key .path ())
220230
221231 return self
222232
@@ -228,20 +238,14 @@ def delete(self):
228238 set on the entity. Whatever is stored remotely using the key on the
229239 entity will be deleted.
230240 """
231- # NOTE: pylint thinks key() is an Entity, hence key().to_protobuf()
232- # is not defined. This is because one branch of the return
233- # in the key() definition returns self.
234- # pylint: disable=maybe-no-member
235- self .dataset ().connection ().delete_entity (
236- dataset_id = self .dataset ().id (), key_pb = self .key ().to_protobuf ())
237- # pylint: enable=maybe-no-member
241+ key = self ._must_key
242+ dataset = key .dataset ()
243+ dataset .connection ().delete_entity (
244+ dataset_id = dataset .id (), key_pb = key .to_protobuf ())
238245
239246 def __repr__ (self ):
240- # An entity should have a key all the time (even if it's partial).
241- if self .key ():
242- # pylint: disable=maybe-no-member
243- return '<Entity%s %s>' % (self .key ().path (),
247+ if self ._key :
248+ return '<Entity%s %s>' % (self ._key .path (),
244249 super (Entity , self ).__repr__ ())
245- # pylint: enable=maybe-no-member
246250 else :
247251 return '<Entity %s>' % (super (Entity , self ).__repr__ ())
0 commit comments