appengine/standard/ndb/entities/snippets.py (162 lines of code) (raw):

# Copyright 2016 Google Inc. # # 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_entity_using_keyword_arguments(): sandy = Account(username="Sandy", userid=123, email="sandy@example.com") return sandy def create_entity_using_attributes(): sandy = Account() sandy.username = "Sandy" sandy.userid = 123 sandy.email = "sandy@example.com" return sandy def create_entity_using_populate(): sandy = Account() sandy.populate(username="Sandy", userid=123, email="sandy@gmail.com") return sandy def demonstrate_model_constructor_type_checking(): bad = Account(username="Sandy", userid="not integer") # raises an exception return bad def demonstrate_entity_attribute_type_checking(sandy): sandy.username = 42 # raises an exception def save_entity(sandy): sandy_key = sandy.put() return sandy_key def get_entity(sandy_key): sandy = sandy_key.get() return sandy def get_key_kind_and_id(sandy_key): kind_string = sandy_key.kind() # returns 'Account' ident = sandy_key.id() # returns '2' return kind_string, ident def get_url_safe_key(sandy_key): url_string = sandy_key.urlsafe() return url_string def get_entity_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_entity_from_key(key): sandy = key.get() sandy.email = "sandy@example.co.uk" sandy.put() def delete_entity(sandy): sandy.key.delete() def create_entity_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_entity_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_entities_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")), ) def create_root_key(): sandy_key = ndb.Key(Account, "sandy@example.com") return sandy_key def create_entity_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_entity(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_entity_using_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_entity_with_defined_properties(): employee = FlexEmployee(name="Sandy", location="SF") return employee class Specialized(ndb.Expando): _default_indexed = False def create_expando_model_entity_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 class ModelWithUser(ndb.Model): user_id = ndb.StringProperty() color = ndb.StringProperty() @classmethod def get_by_user(cls, user): return cls.query().filter(cls.user_id == user.user_id()).get()