Skip to content

Commit 1b87a7e

Browse files
committed
Work around the fact that keys updated from the server have prefixes.
See #528.
1 parent 692cbf1 commit 1b87a7e

2 files changed

Lines changed: 69 additions & 4 deletions

File tree

gcloud/datastore/batch.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,22 @@ def add_auto_id_entity(self, entity):
193193

194194
self._auto_id_entities.append(entity)
195195

196+
def _match_dataset_id(self, other_id):
197+
"""Ensure that `other_id` matches our `dataset_id`.
198+
199+
Helper for :meth:`put` and :meth:`delete`.
200+
201+
:type other_id: string
202+
:param other_id: the dataset ID to compare
203+
204+
:raises: ValueError if `other_id` does not match (even after stripping
205+
any prefix).
206+
"""
207+
other_id = other_id.rsplit('~', 1)[-1]
208+
our_id = self._dataset_id.rsplit('~', 1)[-1]
209+
if other_id != our_id:
210+
raise ValueError("Key must be from same dataset as batch")
211+
196212
def put(self, entity):
197213
"""Remember an entity's state to be saved during ``commit``.
198214
@@ -216,8 +232,7 @@ def put(self, entity):
216232
if entity.key is None:
217233
raise ValueError("Entity must have a key")
218234

219-
if entity.key.dataset_id != self._dataset_id:
220-
raise ValueError("Key must be from same dataset as batch")
235+
self._match_dataset_id(entity.key.dataset_id)
221236

222237
_assign_entity_to_mutation(
223238
self.mutation, entity, self._auto_id_entities)
@@ -234,8 +249,7 @@ def delete(self, key):
234249
if key.is_partial:
235250
raise ValueError("Key must be complete")
236251

237-
if key.dataset_id != self._dataset_id:
238-
raise ValueError("Key must be from same dataset as batch")
252+
self._match_dataset_id(key.dataset_id)
239253

240254
key_pb = key.to_protobuf()
241255
helpers._add_keys_to_request(self.mutation.delete, [key_pb])

gcloud/datastore/test_batch.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,41 @@ def test_put_entity_w_completed_key(self):
203203
deletes = list(batch.mutation.delete)
204204
self.assertEqual(len(deletes), 0)
205205

206+
def test_put_entity_w_completed_key_prefixed_dataset_id(self):
207+
_DATASET = 'DATASET'
208+
_PROPERTIES = {
209+
'foo': 'bar',
210+
'baz': 'qux',
211+
'spam': [1, 2, 3],
212+
'frotz': [], # will be ignored
213+
}
214+
connection = _Connection()
215+
batch = self._makeOne(dataset_id=_DATASET, connection=connection)
216+
entity = _Entity(_PROPERTIES)
217+
entity.exclude_from_indexes = ('baz', 'spam')
218+
key = entity.key = _Key('s~' + _DATASET)
219+
220+
batch.put(entity)
221+
222+
insert_auto_ids = list(batch.mutation.insert_auto_id)
223+
self.assertEqual(len(insert_auto_ids), 0)
224+
upserts = list(batch.mutation.upsert)
225+
self.assertEqual(len(upserts), 1)
226+
227+
upsert = upserts[0]
228+
self.assertEqual(upsert.key, key._key)
229+
props = dict([(prop.name, prop.value) for prop in upsert.property])
230+
self.assertTrue(props['foo'].indexed)
231+
self.assertFalse(props['baz'].indexed)
232+
self.assertTrue(props['spam'].indexed)
233+
self.assertFalse(props['spam'].list_value[0].indexed)
234+
self.assertFalse(props['spam'].list_value[1].indexed)
235+
self.assertFalse(props['spam'].list_value[2].indexed)
236+
self.assertFalse('frotz' in props)
237+
238+
deletes = list(batch.mutation.delete)
239+
self.assertEqual(len(deletes), 0)
240+
206241
def test_delete_w_partial_key(self):
207242
_DATASET = 'DATASET'
208243
connection = _Connection()
@@ -236,6 +271,22 @@ def test_delete_w_completed_key(self):
236271
self.assertEqual(len(deletes), 1)
237272
self.assertEqual(deletes[0], key._key)
238273

274+
def test_delete_w_completed_key_w_prefixed_dataset_id(self):
275+
_DATASET = 'DATASET'
276+
connection = _Connection()
277+
batch = self._makeOne(dataset_id=_DATASET, connection=connection)
278+
key = _Key('s~' + _DATASET)
279+
280+
batch.delete(key)
281+
282+
insert_auto_ids = list(batch.mutation.insert_auto_id)
283+
self.assertEqual(len(insert_auto_ids), 0)
284+
upserts = list(batch.mutation.upsert)
285+
self.assertEqual(len(upserts), 0)
286+
deletes = list(batch.mutation.delete)
287+
self.assertEqual(len(deletes), 1)
288+
self.assertEqual(deletes[0], key._key)
289+
239290
def test_commit(self):
240291
_DATASET = 'DATASET'
241292
connection = _Connection()

0 commit comments

Comments
 (0)