Skip to content

Commit 84d47f9

Browse files
committed
Remove 'Entity.save'.
1 parent 61cb02d commit 84d47f9

File tree

10 files changed

+34
-210
lines changed

10 files changed

+34
-210
lines changed

docs/_components/datastore-getting-started.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Open a Python console and...
4444
>>> entity = datastore.Entity(key=datastore.Key('Person'))
4545
>>> entity['name'] = 'Your name'
4646
>>> entity['age'] = 25
47-
>>> entity.save()
47+
>>> datastore.put([entity])
4848
>>> list(Query(kind='Person').fetch())
4949
[<Entity{...} {'name': 'Your name', 'age': 25}>]
5050

docs/_components/datastore-quickstart.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ you can create entities and save them::
5858
>>> entity = datastore.Entity(key=datastore.Key('Person'))
5959
>>> entity['name'] = 'Your name'
6060
>>> entity['age'] = 25
61-
>>> entity.save()
61+
>>> datastore.put([entity])
6262
>>> list(datastore.Query(kind='Person').fetch())
6363
[<Entity{...} {'name': 'Your name', 'age': 25}>]
6464

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Cloud Datastore
3434
entity = datastore.Entity(key=datastore.Key('Person'))
3535
entity['name'] = 'Your name'
3636
entity['age'] = 25
37-
entity.save()
37+
datastore.put([entity])
3838
3939
Cloud Storage
4040
~~~~~~~~~~~~~

gcloud/datastore/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
from gcloud.datastore.api import allocate_ids
5454
from gcloud.datastore.api import delete
5555
from gcloud.datastore.api import get
56+
from gcloud.datastore.api import put
5657
from gcloud.datastore.batch import Batch
5758
from gcloud.datastore.connection import Connection
5859
from gcloud.datastore.entity import Entity

gcloud/datastore/demo/demo.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
toy.update({'name': 'Toy'})
2929

3030
# Now let's save it to our datastore:
31-
toy.save()
31+
datastore.put([toy])
3232

3333
# If we look it up by its key, we should find it...
3434
print(datastore.get([toy.key]))
@@ -55,7 +55,7 @@
5555
entity = datastore.Entity(key)
5656
entity['name'] = name
5757
entity['age'] = age
58-
entity.save()
58+
datastore.put([entity])
5959
# We'll start by look at all Thing entities:
6060
query = datastore.Query(kind='Thing')
6161

@@ -76,41 +76,41 @@
7676

7777
# You can also work inside a transaction.
7878
# (Check the official docs for explanations of what's happening here.)
79-
with datastore.Transaction():
79+
with datastore.Transaction() as xact:
8080
print('Creating and saving an entity...')
8181
key = datastore.Key('Thing', 'foo')
8282
thing = datastore.Entity(key)
8383
thing['age'] = 10
84-
thing.save()
84+
xact.put(thing)
8585

8686
print('Creating and saving another entity...')
8787
key2 = datastore.Key('Thing', 'bar')
8888
thing2 = datastore.Entity(key2)
8989
thing2['age'] = 15
90-
thing2.save()
90+
xact.put(thing2)
9191

9292
print('Committing the transaction...')
9393

9494
# Now that the transaction is commited, let's delete the entities.
9595
datastore.delete([key, key2])
9696

9797
# To rollback a transaction, just call .rollback()
98-
with datastore.Transaction() as t:
98+
with datastore.Transaction() as xact:
9999
key = datastore.Key('Thing', 'another')
100100
thing = datastore.Entity(key)
101-
thing.save()
102-
t.rollback()
101+
xact.put(thing)
102+
xact.rollback()
103103

104104
# Let's check if the entity was actually created:
105105
created = datastore.get([key])
106106
print('yes' if created else 'no')
107107

108108
# Remember, a key won't be complete until the transaction is commited.
109109
# That is, while inside the transaction block, thing.key will be incomplete.
110-
with datastore.Transaction():
110+
with datastore.Transaction() as xact:
111111
key = datastore.Key('Thing') # partial
112112
thing = datastore.Entity(key)
113-
thing.save()
113+
xact.put(thing)
114114
print(thing.key) # This will still be partial
115115

116116
print(thing.key) # This will be complete

gcloud/datastore/entity.py

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

1515
"""Class for representing a single entity in the Cloud Datastore."""
1616

17-
from gcloud.datastore import _implicit_environ
18-
1917

2018
class NoKey(RuntimeError):
2119
"""Exception raised by Entity methods which require a key."""
@@ -70,8 +68,8 @@ class Entity(dict):
7068
any decoding / encoding step.
7169
7270
:type key: :class:`gcloud.datastore.key.Key`
73-
:param key: Optional key to be set on entity. Required for :meth:`save()`
74-
or :meth:`reload()`.
71+
:param key: Optional key to be set on entity. Required for
72+
:fund:`gcloud.datastore.put()`
7573
7674
:type exclude_from_indexes: tuple of string
7775
:param exclude_from_indexes: Names of fields whose values are not to be
@@ -104,55 +102,6 @@ def exclude_from_indexes(self):
104102
"""
105103
return frozenset(self._exclude_from_indexes)
106104

107-
@property
108-
def _must_key(self):
109-
"""Return our key, or raise NoKey if not set.
110-
111-
:rtype: :class:`gcloud.datastore.key.Key`.
112-
:returns: The entity's key.
113-
:raises: :class:`NoKey` if no key is set.
114-
"""
115-
if self.key is None:
116-
raise NoKey()
117-
return self.key
118-
119-
def save(self, connection=None):
120-
"""Save the entity in the Cloud Datastore.
121-
122-
.. note::
123-
Any existing properties for the entity will be replaced by those
124-
currently set on this instance. Already-stored properties which do
125-
not correspond to keys set on this instance will be removed from
126-
the datastore.
127-
128-
.. note::
129-
Property values which are "text" (``unicode`` in Python2, ``str`` in
130-
Python3) map to 'string_value' in the datastore; values which are
131-
"bytes" (``str`` in Python2, ``bytes`` in Python3) map to
132-
'blob_value'.
133-
134-
:type connection: :class:`gcloud.datastore.connection.Connection`
135-
:param connection: Optional connection used to connect to datastore.
136-
"""
137-
connection = connection or _implicit_environ.CONNECTION
138-
139-
key = self._must_key
140-
assigned, new_id = connection.save_entity(
141-
dataset_id=key.dataset_id,
142-
key_pb=key.to_protobuf(),
143-
properties=dict(self),
144-
exclude_from_indexes=self.exclude_from_indexes)
145-
146-
# If we are in a transaction and the current entity needs an
147-
# automatically assigned ID, tell the transaction where to put that.
148-
transaction = connection.transaction()
149-
if transaction and key.is_partial:
150-
transaction.add_auto_id_entity(self)
151-
152-
if assigned:
153-
# Update the key (which may have been altered).
154-
self.key = self.key.completed_key(new_id)
155-
156105
def __repr__(self):
157106
if self.key:
158107
return '<Entity%s %s>' % (self.key.path,

gcloud/datastore/test_entity.py

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -53,79 +53,6 @@ def test_ctor_explicit(self):
5353
self.assertEqual(sorted(entity.exclude_from_indexes),
5454
sorted(_EXCLUDE_FROM_INDEXES))
5555

56-
def test__must_key_no_key(self):
57-
from gcloud.datastore.entity import NoKey
58-
59-
entity = self._makeOne()
60-
self.assertRaises(NoKey, getattr, entity, '_must_key')
61-
62-
def test_save_no_key(self):
63-
from gcloud.datastore.entity import NoKey
64-
65-
entity = self._makeOne()
66-
entity['foo'] = 'Foo'
67-
self.assertRaises(NoKey, entity.save)
68-
69-
def test_save_wo_transaction_wo_auto_id_wo_returned_key(self):
70-
connection = _Connection()
71-
key = _Key()
72-
entity = self._makeOne(key=key)
73-
entity['foo'] = 'Foo'
74-
entity.save(connection=connection)
75-
self.assertEqual(entity['foo'], 'Foo')
76-
self.assertEqual(connection._saved,
77-
(_DATASET_ID, 'KEY', {'foo': 'Foo'}, ()))
78-
self.assertEqual(key._path, None)
79-
80-
def test_save_w_transaction_wo_partial_key(self):
81-
connection = _Connection()
82-
transaction = connection._transaction = _Transaction()
83-
key = _Key()
84-
entity = self._makeOne(key=key)
85-
entity['foo'] = 'Foo'
86-
entity.save(connection=connection)
87-
self.assertEqual(entity['foo'], 'Foo')
88-
self.assertEqual(connection._saved,
89-
(_DATASET_ID, 'KEY', {'foo': 'Foo'}, ()))
90-
self.assertEqual(transaction._added, ())
91-
self.assertEqual(key._path, None)
92-
93-
def test_save_w_transaction_w_partial_key(self):
94-
connection = _Connection()
95-
transaction = connection._transaction = _Transaction()
96-
key = _Key()
97-
key._partial = True
98-
entity = self._makeOne(key=key)
99-
entity['foo'] = 'Foo'
100-
entity.save(connection=connection)
101-
self.assertEqual(entity['foo'], 'Foo')
102-
self.assertEqual(connection._saved,
103-
(_DATASET_ID, 'KEY', {'foo': 'Foo'}, ()))
104-
self.assertEqual(transaction._added, (entity,))
105-
self.assertEqual(key._path, None)
106-
107-
def test_save_w_returned_key_exclude_from_indexes(self):
108-
from gcloud.datastore import datastore_v1_pb2 as datastore_pb
109-
from gcloud.datastore.key import Key
110-
111-
key_pb = datastore_pb.Key()
112-
key_pb.partition_id.dataset_id = _DATASET_ID
113-
key_pb.path_element.add(kind=_KIND, id=_ID)
114-
connection = _Connection()
115-
connection._save_result = (True, _ID)
116-
key = Key('KIND', dataset_id=_DATASET_ID)
117-
entity = self._makeOne(key=key, exclude_from_indexes=['foo'])
118-
entity['foo'] = 'Foo'
119-
entity.save(connection=connection)
120-
self.assertEqual(entity['foo'], 'Foo')
121-
self.assertEqual(connection._saved[0], _DATASET_ID)
122-
self.assertEqual(connection._saved[1], key.to_protobuf())
123-
self.assertEqual(connection._saved[2], {'foo': 'Foo'})
124-
self.assertEqual(connection._saved[3], ('foo',))
125-
self.assertEqual(len(connection._saved), 4)
126-
127-
self.assertEqual(entity.key._path, [{'kind': _KIND, 'id': _ID}])
128-
12956
def test___repr___no_key_empty(self):
13057
entity = self._makeOne()
13158
self.assertEqual(repr(entity), '<Entity {}>')
@@ -149,38 +76,6 @@ class _Key(object):
14976
def __init__(self, dataset_id=_DATASET_ID):
15077
self.dataset_id = dataset_id
15178

152-
def to_protobuf(self):
153-
return self._key
154-
155-
@property
156-
def is_partial(self):
157-
return self._partial
158-
15979
@property
16080
def path(self):
16181
return self._path
162-
163-
164-
class _Connection(object):
165-
_transaction = _saved = _deleted = None
166-
_save_result = (False, None)
167-
168-
def transaction(self):
169-
return self._transaction
170-
171-
def save_entity(self, dataset_id, key_pb, properties,
172-
exclude_from_indexes=()):
173-
self._saved = (dataset_id, key_pb, properties,
174-
tuple(exclude_from_indexes))
175-
return self._save_result
176-
177-
178-
class _Transaction(object):
179-
_added = ()
180-
181-
def __nonzero__(self):
182-
return True
183-
__bool__ = __nonzero__
184-
185-
def add_auto_id_entity(self, entity):
186-
self._added += (entity,)

gcloud/datastore/transaction.py

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ class Transaction(Batch):
3232
3333
>>> datastore.set_defaults()
3434
35-
>>> with Transaction()
36-
... entity1.save()
37-
... entity2.save()
35+
>>> with Transaction() as xact:
36+
... datastore.put(entity1)
37+
... datastore.put(entity2)
3838
3939
Because it derives from :class:`Batch`, :class`Transaction` also provides
4040
:meth:`put` and :meth:`delete` methods::
4141
42-
>>> with Transaction()
43-
... transaction.put(entity1)
44-
... transaction.delete(entity2.key)
42+
>>> with Transaction() as xact:
43+
... xact.put(entity1)
44+
... xact.delete(entity2.key)
4545
4646
By default, the transaction is rolled back if the transaction block
4747
exits with an error::
@@ -59,7 +59,7 @@ class Transaction(Batch):
5959
6060
>>> with Transaction():
6161
... entity = Entity(key=Key('Thing'))
62-
... entity.save()
62+
... datastore.put([entity])
6363
6464
``entity`` won't have a complete Key until the transaction is
6565
committed.
@@ -69,7 +69,7 @@ class Transaction(Batch):
6969
7070
>>> with Transaction():
7171
... entity = Entity(key=Key('Thing'))
72-
... entity.save()
72+
... datastore.put([entity])
7373
... assert entity.key.is_partial # There is no ID on this key.
7474
>>> assert not entity.key.is_partial # There *is* an ID.
7575
@@ -89,34 +89,13 @@ class Transaction(Batch):
8989
>>> transaction.begin()
9090
9191
>>> entity = Entity(key=Key('Thing'))
92-
>>> entity.save()
92+
>>> datastore.put([entity])
9393
9494
>>> if error:
9595
... transaction.rollback()
9696
... else:
9797
... transaction.commit()
9898
99-
For now, this library will enforce a rule of one transaction per
100-
connection. That is, If you want to work with two transactions at
101-
the same time (for whatever reason), that must happen over two
102-
separate :class:`gcloud.datastore.connection.Connection` s.
103-
104-
For example, this is perfectly valid::
105-
106-
>>> with Transaction():
107-
... entity = Entity(key=Key('Thing'))
108-
... entity.save()
109-
110-
However, this **wouldn't** be acceptable::
111-
112-
>>> with Transaction():
113-
... Entity(key=Key('Thing')).save()
114-
... with Transaction():
115-
... Entity(key=Key('Thing')).save()
116-
117-
Technically, it looks like the Protobuf API supports this type of
118-
pattern, however it makes the code particularly messy.
119-
12099
:type dataset_id: string
121100
:param dataset_id: The ID of the dataset.
122101

0 commit comments

Comments
 (0)