-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Expand file tree
/
Copy pathsnippets.py
More file actions
263 lines (174 loc) · 6.66 KB
/
snippets.py
File metadata and controls
263 lines (174 loc) · 6.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from google.appengine.ext import ndb
class Account(ndb.Model):
username = ndb.StringProperty()
userid = ndb.IntegerProperty()
email = ndb.StringProperty()
def create_model_using_keyword_arguments():
sandy = Account(
username='Sandy', userid=123, email='sandy@example.com')
return sandy
def create_model_using_attributes():
sandy = Account()
sandy.username = 'Sandy'
sandy.userid = 123
sandy.email = 'sandy@example.com'
return sandy
def demonstrate_model_constructor_type_checking():
bad = Account(
username='Sandy', userid='not integer') # raises an exception
return bad
def dmonstrate_model_attribute_type_checking(sandy):
sandy.username = 42 # raises an exception
def save_model(sandy):
sandy_key = sandy.put()
return sandy_key
def get_url_safe_key(sandy_key):
url_string = sandy_key.urlsafe()
return url_string
def get_model_from_url_safe_key(url_string):
sandy_key = ndb.Key(urlsafe=url_string)
sandy = sandy_key.get()
return sandy
def get_key_and_numeric_id_from_url_safe_key(url_string):
key = ndb.Key(urlsafe=url_string)
kind_string = key.kind()
ident = key.id()
return key, ident, kind_string
def update_model_from_key(key):
sandy = key.get()
sandy.email = 'sandy@example.co.uk'
sandy.put()
def delete_model(sandy):
sandy.key.delete()
def create_model_with_named_key():
account = Account(
username='Sandy', userid=1234, email='sandy@example.com',
id='sandy@example.com')
return account.key.id() # returns 'sandy@example.com'
def set_key_directly(account):
account.key = ndb.Key('Account', 'sandy@example.com')
# You can also use the model class object itself, rather than its name,
# to specify the entity's kind:
account.key = ndb.Key(Account, 'sandy@example.com')
def create_model_with_generated_id():
# note: no id kwarg
account = Account(username='Sandy', userid=1234, email='sandy@example.com')
account.put()
# Account.key will now have a key of the form: ndb.Key(Account, 71321839)
# where the value 71321839 was generated by Datastore for us.
return account
class Revision(ndb.Model):
message_text = ndb.StringProperty()
def demonstrate_models_with_parent_hierarchy():
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '2')
ndb.Key('Account', 'larry@example.com', 'Message', 456, 'Revision', '1')
ndb.Key('Account', 'larry@example.com', 'Message', 789, 'Revision', '2')
def equivalent_ways_to_define_key_with_parent():
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')
ndb.Key('Revision', '1', parent=ndb.Key(
'Account', 'sandy@example.com', 'Message', 123))
ndb.Key('Revision', '1', parent=ndb.Key(
'Message', 123, parent=ndb.Key('Account', 'sandy@example.com')))
sandy_key = ndb.Key(Account, 'sandy@example.com')
return sandy_key
def create_model_with_parent_keys():
account_key = ndb.Key(Account, 'sandy@example.com')
# Ask Datastore to allocate an ID.
new_id = ndb.Model.allocate_ids(size=1, parent=account_key)[0]
# Datastore returns us an integer ID that we can use to create the message
# key
message_key = ndb.Key('Message', new_id, parent=account_key)
# Now we can put the message into Datastore
initial_revision = Revision(
message_text='Hello', id='1', parent=message_key)
initial_revision.put()
return initial_revision
def get_parent_key_of_model(initial_revision):
message_key = initial_revision.key.parent()
return message_key
def operate_on_multiple_keys_at_once(list_of_entities):
list_of_keys = ndb.put_multi(list_of_entities)
list_of_entities = ndb.get_multi(list_of_keys)
ndb.delete_multi(list_of_keys)
class Mine(ndb.Expando):
pass
def create_expando_model():
e = Mine()
e.foo = 1
e.bar = 'blah'
e.tags = ['exp', 'and', 'oh']
e.put()
return e
def get_properties_defined_on_expando(e):
return e._properties
# {
# 'foo': GenericProperty('foo'),
# 'bar': GenericProperty('bar'),
# 'tags': GenericProperty('tags', repeated=True)
# }
class FlexEmployee(ndb.Expando):
name = ndb.StringProperty()
age = ndb.IntegerProperty()
def create_expando_model_with_defined_properties():
employee = FlexEmployee(name='Sandy', location='SF')
return employee
class Specialized(ndb.Expando):
_default_indexed = False
def create_expando_model_that_isnt_indexed_by_default():
e = Specialized(foo='a', bar=['b'])
return e._properties
# {
# 'foo': GenericProperty('foo', indexed=False),
# 'bar': GenericProperty('bar', indexed=False, repeated=True)
# }
def demonstrate_wrong_way_to_query_expando():
FlexEmployee.query(FlexEmployee.location == 'SF')
def demonstrate_right_way_to_query_expando():
FlexEmployee.query(ndb.GenericProperty('location') == 'SF')
notification = None
def _notify(message):
global notification
notification = message
class Friend(ndb.Model):
name = ndb.StringProperty()
def _pre_put_hook(self):
_notify('Gee wiz I have a new friend!')
@classmethod
def _post_delete_hook(cls, key, future):
_notify('I have found occasion to rethink our friendship.')
def demonstrate_model_put_and_delete_hooks():
f = Friend()
f.name = 'Carole King'
f.put() # _pre_put_hook is called
yield f
fut = f.key.delete_async() # _post_delete_hook not yet called
fut.get_result() # _post_delete_hook is called
yield f
class MyModel(ndb.Model):
pass
def reserve_model_ids():
first, last = MyModel.allocate_ids(100)
return first, last
def reserve_model_ids_with_a_parent(p):
first, last = MyModel.allocate_ids(100, parent=p)
return first, last
def construct_keys_from_range_of_reserved_ids(first, last):
keys = [ndb.Key(MyModel, id) for id in range(first, last+1)]
return keys
def reserve_model_ids_up_to(N):
first, last = MyModel.allocate_ids(max=N)
return first, last