Skip to content

Commit 6078fc1

Browse files
committed
Add 'insert_auto_ids' support to 'Batch'.
Follow-on to #509.
1 parent 3a448f3 commit 6078fc1

2 files changed

Lines changed: 64 additions & 5 deletions

File tree

gcloud/datastore/batch.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def __init__(self, dataset_id=None, connection=None):
7272
'a dataset ID set.')
7373

7474
self._mutation = datastore_pb.Mutation()
75+
self._auto_id_entities = []
7576

7677
@property
7778
def dataset_id(self):
@@ -137,6 +138,9 @@ def put(self, entity):
137138
self.dataset_id, key_pb, properties,
138139
exclude_from_indexes=exclude, mutation=self.mutation)
139140

141+
if entity.key.is_partial:
142+
self._auto_id_entities.append(entity)
143+
140144
def delete(self, key):
141145
"""Remember a key to be deleted durring ``commit``.
142146
@@ -159,7 +163,11 @@ def commit(self):
159163
however it can be called explicitly if you don't want to use a
160164
context manager.
161165
"""
162-
self.connection.commit(self._dataset_id, self.mutation)
166+
response = self.connection.commit(self._dataset_id, self.mutation)
167+
for new_key_pb, entity in zip(response.insert_auto_id_key,
168+
self._auto_id_entities):
169+
new_id = new_key_pb.path_element[-1].id
170+
entity.key = entity.key.completed_key(new_id)
163171

164172
def __enter__(self):
165173
return self

gcloud/datastore/test_batch.py

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def test_ctor_explicit(self):
4646
self.assertEqual(batch.dataset_id, _DATASET)
4747
self.assertEqual(batch.connection, connection)
4848
self.assertTrue(isinstance(batch.mutation, Mutation))
49+
self.assertEqual(batch._auto_id_entities, [])
4950

5051
def test_ctor_implicit(self):
5152
from gcloud._testing import _Monkey
@@ -62,6 +63,7 @@ def test_ctor_implicit(self):
6263
self.assertEqual(batch.dataset_id, DATASET_ID)
6364
self.assertEqual(batch.connection, CONNECTION)
6465
self.assertTrue(isinstance(batch.mutation, Mutation))
66+
self.assertEqual(batch._auto_id_entities, [])
6567

6668
def test_put_entity_wo_key(self):
6769
_DATASET = 'DATASET'
@@ -70,7 +72,23 @@ def test_put_entity_wo_key(self):
7072

7173
self.assertRaises(ValueError, batch.put, _Entity())
7274

73-
def test_put_entity_w_key(self):
75+
def test_put_entity_w_partial_key(self):
76+
_DATASET = 'DATASET'
77+
_PROPERTIES = {'foo': 'bar'}
78+
connection = _Connection()
79+
batch = self._makeOne(dataset_id=_DATASET, connection=connection)
80+
entity = _Entity(_PROPERTIES)
81+
key = entity.key = _Key(_DATASET)
82+
key._partial = True
83+
84+
batch.put(entity)
85+
86+
self.assertEqual(
87+
connection._saved,
88+
(_DATASET, key._key, _PROPERTIES, (), batch.mutation))
89+
self.assertEqual(batch._auto_id_entities, [entity])
90+
91+
def test_put_entity_w_completed_key(self):
7492
_DATASET = 'DATASET'
7593
_PROPERTIES = {'foo': 'bar'}
7694
connection = _Connection()
@@ -114,6 +132,22 @@ def test_commit(self):
114132

115133
self.assertEqual(connection._committed, (_DATASET, batch.mutation))
116134

135+
def test_commit_w_auto_id_entities(self):
136+
_DATASET = 'DATASET'
137+
_NEW_ID = 1234
138+
connection = _Connection(_NEW_ID)
139+
batch = self._makeOne(dataset_id=_DATASET, connection=connection)
140+
entity = _Entity({})
141+
key = entity.key = _Key(_DATASET)
142+
key._partial = True
143+
batch._auto_id_entities.append(entity)
144+
145+
batch.commit()
146+
147+
self.assertEqual(connection._committed, (_DATASET, batch.mutation))
148+
self.assertFalse(key._partial)
149+
self.assertEqual(key._id, _NEW_ID)
150+
117151
def test_as_context_mgr_wo_error(self):
118152
_DATASET = 'DATASET'
119153
_PROPERTIES = {'foo': 'bar'}
@@ -154,16 +188,28 @@ def test_as_context_mgr_w_error(self):
154188
class _CommitResult(object):
155189

156190
def __init__(self, *new_keys):
157-
self.insert_auto_id_key = new_keys
191+
self.insert_auto_id_key = [_KeyPB(key) for key in new_keys]
192+
193+
194+
class _PathElementPB(object):
195+
196+
def __init__(self, id):
197+
self.id = id
198+
199+
200+
class _KeyPB(object):
201+
202+
def __init__(self, id):
203+
self.path_element = [_PathElementPB(id)]
158204

159205

160206
class _Connection(object):
161207
_marker = object()
162208
_committed = _saved = _deleted = None
163209
_save_result = (False, None)
164210

165-
def __init__(self):
166-
self._commit_result = _CommitResult()
211+
def __init__(self, *new_keys):
212+
self._commit_result = _CommitResult(*new_keys)
167213

168214
def save_entity(self, dataset_id, key_pb, properties,
169215
exclude_from_indexes=(), mutation=None):
@@ -201,3 +247,8 @@ def is_partial(self):
201247

202248
def to_protobuf(self):
203249
return self._key
250+
251+
def completed_key(self, new_id):
252+
assert self._partial
253+
self._id = new_id
254+
self._partial = False

0 commit comments

Comments
 (0)