1515"""Class for representing a single entity in the Cloud Datastore."""
1616
1717from gcloud .datastore import _implicit_environ
18- from gcloud .datastore .key import Key
1918
2019
2120class NoKey (RuntimeError ):
2221 """Exception raised by Entity methods which require a key."""
2322
2423
25- class NoDataset (RuntimeError ):
26- """Exception raised by Entity methods which require a dataset."""
27-
28-
2924class Entity (dict ):
3025 """Entities are akin to rows in a relational database
3126
@@ -75,72 +70,21 @@ class Entity(dict):
7570 Python3), will be saved using the 'blob_value' field, without
7671 any decoding / encoding step.
7772
78- :type dataset: :class:`gcloud.datastore.dataset.Dataset`
79- :param dataset: The dataset in which this entity belongs.
80-
81- :type kind: string
82- :param kind: The kind of entity this is, akin to a table name in a
83- relational database.
84-
85- :type dataset: :class:`gcloud.datastore.dataset.Dataset`, or None
86- :param dataset: the Dataset instance associated with this entity.
87-
88- :type kind: str
89- :param kind: the "kind" of the entity (see
90- https://cloud.google.com/datastore/docs/concepts/entities#Datastore_Kinds_and_identifiers)
73+ :type key: :class:`gcloud.datastore.key.Key`
74+ :param key: Optional key to be set on entity. Required for save() or
75+ reload().
9176
77+ :type exclude_from_indexes: `tuple` of :class:`str`
9278 :param exclude_from_indexes: names of fields whose values are not to be
9379 indexed for this entity.
9480 """
9581
96- def __init__ (self , dataset = None , kind = None , exclude_from_indexes = ()):
82+ def __init__ (self , key = None , exclude_from_indexes = ()):
9783 super (Entity , self ).__init__ ()
98- # Does not inherit directly from object, so we don't use
99- # _implicit_environ._DatastoreBase to avoid split MRO.
100- self ._dataset = dataset or _implicit_environ .DATASET
101- if kind :
102- self ._key = Key (kind , dataset_id = self .dataset ().id ())
103- else :
104- self ._key = None
84+ self .key = key
10585 self ._exclude_from_indexes = set (exclude_from_indexes )
10686
107- def dataset (self ):
108- """Get the :class:`.dataset.Dataset` in which this entity belongs.
109-
110- .. note::
111- This is based on the :class:`gcloud.datastore.key.Key` set on the
112- entity. That means that if you have no key set, the dataset might
113- be `None`. It also means that if you change the key on the entity,
114- this will refer to that key's dataset.
115-
116- :rtype: :class:`gcloud.datastore.dataset.Dataset`
117- :returns: The Dataset containing the entity if there is a key,
118- else None.
119- """
120- return self ._dataset
121-
122- def key (self , key = None ):
123- """Get or set the :class:`.datastore.key.Key` on the current entity.
124-
125- :type key: :class:`glcouddatastore.key.Key`
126- :param key: The key you want to set on the entity.
127-
128- :rtype: :class:`gcloud.datastore.key.Key` or :class:`Entity`.
129- :returns: Either the current key (on get) or the current
130- object (on set).
131-
132- >>> entity.key(my_other_key) # This returns the original entity.
133- <Entity[{'kind': 'OtherKeyKind', 'id': 1234}] {'property': 'value'}>
134- >>> entity.key() # This returns the key.
135- <Key[{'kind': 'OtherKeyKind', 'id': 1234}]>
136- """
137-
138- if key is not None :
139- self ._key = key
140- return self
141- else :
142- return self ._key
143-
87+ @property
14488 def kind (self ):
14589 """Get the kind of the current entity.
14690
@@ -150,32 +94,17 @@ def kind(self):
15094 of the entity at all, just the properties and a pointer to a
15195 Key which knows its Kind.
15296 """
97+ if self .key :
98+ return self .key .kind
15399
154- if self ._key :
155- return self ._key .kind
156-
100+ @property
157101 def exclude_from_indexes (self ):
158102 """Names of fields which are *not* to be indexed for this entity.
159103
160104 :rtype: sequence of field names
161105 """
162106 return frozenset (self ._exclude_from_indexes )
163107
164- @classmethod
165- def from_key (cls , key , dataset = None ):
166- """Create entity based on :class:`.datastore.key.Key`.
167-
168- .. note:: This is a factory method.
169-
170- :type key: :class:`gcloud.datastore.key.Key`
171- :param key: The key for the entity.
172-
173- :returns: The :class:`Entity` derived from the
174- :class:`gcloud.datastore.key.Key`.
175- """
176-
177- return cls (dataset ).key (key )
178-
179108 @property
180109 def _must_key (self ):
181110 """Return our key, or raise NoKey if not set.
@@ -184,23 +113,11 @@ def _must_key(self):
184113 :returns: our key
185114 :raises: NoKey if key is None
186115 """
187- if self ._key is None :
116+ if self .key is None :
188117 raise NoKey ()
189- return self ._key
190-
191- @property
192- def _must_dataset (self ):
193- """Return our dataset, or raise NoDataset if not set.
194-
195- :rtype: :class:`gcloud.datastore.key.Key`.
196- :returns: our key
197- :raises: NoDataset if key is None
198- """
199- if self ._dataset is None :
200- raise NoDataset ()
201- return self ._dataset
118+ return self .key
202119
203- def reload (self ):
120+ def reload (self , connection = None ):
204121 """Reloads the contents of this entity from the datastore.
205122
206123 This method takes the :class:`gcloud.datastore.key.Key`, loads all
@@ -211,16 +128,19 @@ def reload(self):
211128 This will override any existing properties if a different value
212129 exists remotely, however it will *not* override any properties that
213130 exist only locally.
131+
132+ :type connection: :class:`gcloud.datastore.connection.Connection`
133+ :param connection: Optional connection used to connect to datastore.
214134 """
135+ connection = connection or _implicit_environ .CONNECTION
136+
215137 key = self ._must_key
216- connection = self ._must_dataset .connection ()
217138 entity = key .get (connection = connection )
218139
219140 if entity :
220141 self .update (entity )
221- return self
222142
223- def save (self ):
143+ def save (self , connection = None ):
224144 """Save the entity in the Cloud Datastore.
225145
226146 .. note::
@@ -234,17 +154,17 @@ def save(self):
234154 Python3) map to 'string_value' in the datastore; values which are
235155 "bytes" ('str' in Python2, 'bytes' in Python3) map to 'blob_value'.
236156
237- :rtype : :class:`gcloud.datastore.entity.Entity `
238- :returns: The entity with a possibly updated Key .
157+ :type connection : :class:`gcloud.datastore.connection.Connection `
158+ :param connection: Optional connection used to connect to datastore .
239159 """
160+ connection = connection or _implicit_environ .CONNECTION
161+
240162 key = self ._must_key
241- dataset = self ._must_dataset
242- connection = dataset .connection ()
243163 assigned , new_id = connection .save_entity (
244- dataset_id = dataset . id () ,
164+ dataset_id = key . dataset_id ,
245165 key_pb = key .to_protobuf (),
246166 properties = dict (self ),
247- exclude_from_indexes = self .exclude_from_indexes () )
167+ exclude_from_indexes = self .exclude_from_indexes )
248168
249169 # If we are in a transaction and the current entity needs an
250170 # automatically assigned ID, tell the transaction where to put that.
@@ -254,13 +174,11 @@ def save(self):
254174
255175 if assigned :
256176 # Update the key (which may have been altered).
257- self .key (self .key ().completed_key (new_id ))
258-
259- return self
177+ self .key = self .key .completed_key (new_id )
260178
261179 def __repr__ (self ):
262- if self ._key :
263- return '<Entity%s %s>' % (self ._key .path ,
180+ if self .key :
181+ return '<Entity%s %s>' % (self .key .path ,
264182 super (Entity , self ).__repr__ ())
265183 else :
266184 return '<Entity %s>' % (super (Entity , self ).__repr__ ())
0 commit comments