Skip to content

Commit

Permalink
Added examples from appengine-ndb-snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
elibixby committed May 7, 2015
1 parent 765ba16 commit d0188c0
Show file tree
Hide file tree
Showing 14 changed files with 852 additions and 0 deletions.
6 changes: 6 additions & 0 deletions datastore/ndb/modeling/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
appengine-ndb-snippets
======================

= modeling

Sample code for (Modeling Entity Relationships)[https://cloud.google.com/appengine/articles/modeling].
84 changes: 84 additions & 0 deletions datastore/ndb/modeling/contact_with_group_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Copyright 2014 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.

"""Models for representing an address book contact with grouping.
This module provides models which implement structured properties,
strongly consistent querying, and one-to-many grouping.
Classes: Contact, Group, PhoneNumber
"""


from google.appengine.ext import ndb


# [START contact_with_group_models]
class PhoneNumber(ndb.Model):
"""A model representing a phone number."""
phone_type = ndb.StringProperty(
choices=('home', 'work', 'fax', 'mobile', 'other'))
number = ndb.StringProperty()


class Group(ndb.Model):
"""A model representing groups.
Expects to have a parent key with the id of the addressbook owner.
Example: assume my username is tmatsuo
addrbook_key = ndb.Key('AddressBook', 'tmatsuo')
friends = models.Group(parent=addrbook_key, name="friends")
friends.put()
"""
name = ndb.StringProperty()
description = ndb.TextProperty()

@property
def members(self):
"""Returns a query object with myself as an ancestor."""
return Contact.query(ancestor=self.key.parent()).filter(
Contact.groups == self.key)


class Contact(ndb.Model):
"""A Contact model that uses repeated KeyProperty.
Expects to have a parent key with the id of the addressbook owner.
Example: assume my username is tmatsuo
addrbook_key = ndb.Key('AddressBook', 'tmatsuo')
mary = models.Contact(parent=addrbook_key, name='mary', ...)
mary.put()
"""
# Basic info.
name = ndb.StringProperty()
birth_day = ndb.DateProperty()

# Address info.
address = ndb.StringProperty()

phone_numbers = ndb.StructuredProperty(PhoneNumber, repeated=True)

# Company info.
company_title = ndb.StringProperty()
company_name = ndb.StringProperty()
company_description = ndb.TextProperty()
company_address = ndb.StringProperty()

# Group affiliation
groups = ndb.KeyProperty(Group, repeated=True)
# [END contact_with_group_models]
64 changes: 64 additions & 0 deletions datastore/ndb/modeling/keyproperty_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2014 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.


"""Models for representing a contact with multiple phone numbers.
This module provides models with a relationship with ndb.KeyProperty to
allow a single contact to have multiple phone numbers.
Classes: Contact, PhoneNumber
"""


# In the original article, it uses ReferenceProperty on the
# PhoneNumber model. With ndb, there is no ReferenceProperty any more,
# so here we use KeyProperty first. However this pattern has a
# consistensy issue, shown in the test_fails function in
# test/test_keyproperty_models.py.


from google.appengine.ext import ndb


# [START keyproperty_models]
class Contact(ndb.Model):
"""A Contact model with KeyProperty."""
# Basic info.
name = ndb.StringProperty()
birth_day = ndb.DateProperty()

# Address info.
address = ndb.StringProperty()

# Company info.
company_title = ndb.StringProperty()
company_name = ndb.StringProperty()
company_description = ndb.TextProperty()
company_address = ndb.StringProperty()

# The original phone_number property has been replaced by
# the following property.
@property
def phone_numbers(self):
return PhoneNumber.query(PhoneNumber.contact == self.key)


class PhoneNumber(ndb.Model):
"""A model representing a phone number."""
contact = ndb.KeyProperty(Contact)
phone_type = ndb.StringProperty(
choices=('home', 'work', 'fax', 'mobile', 'other'))
number = ndb.StringProperty()
# [END keyproperty_models]
47 changes: 47 additions & 0 deletions datastore/ndb/modeling/naive_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2014 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.

"""A simple model for representing an address book contact.
This module provides a simple model, Contact.
"""

# This is the first naive model for starting the article. In the
# older version of this article with db module, we used
# PhoneNumberProperty and PostalAddressProperty. With ndb, there are
# no properties like those, so we just use StringProperty instead.


from google.appengine.ext import ndb


# [START naive_models]
class Contact(ndb.Model):
"""A naive Contact model."""
# Basic info.
name = ndb.StringProperty()
birth_day = ndb.DateProperty()

# Address info.
address = ndb.StringProperty()

# Phone info.
phone_number = ndb.StringProperty()

# Company info.
company_title = ndb.StringProperty()
company_name = ndb.StringProperty()
company_description = ndb.TextProperty()
company_address = ndb.StringProperty()
# [END naive_models]
63 changes: 63 additions & 0 deletions datastore/ndb/modeling/parent_child_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2014 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.

"""Models representing a contact with multiple phone numbers.
This module provides models with a relationship with parent-child
relationship to allow strong consistent query.
Classes: Contact, PhoneNumber
"""


# In the original article, it uses ReferenceProperty on the
# PhoneNumber model. With ndb, there is no ReferenceProperty any more,
# so here we use Parent/Child relationship instead.


from google.appengine.ext import ndb


# [START parent_child_models]
class Contact(ndb.Model):
"""A Contact model with Parent/Child relationship."""
# Basic info.
name = ndb.StringProperty()
birth_day = ndb.DateProperty()

# Address info.
address = ndb.StringProperty()

# Company info.
company_title = ndb.StringProperty()
company_name = ndb.StringProperty()
company_description = ndb.TextProperty()
company_address = ndb.StringProperty()

# The original phone_number property has been replaced by
# the following property.
@property
def phone_numbers(self):
return PhoneNumber.query(ancestor=self.key)


class PhoneNumber(ndb.Model):
"""A model representing a phone number.
Expects to have Contact's key as the parent key.
"""
phone_type = ndb.StringProperty(
choices=('home', 'work', 'fax', 'mobile', 'other'))
number = ndb.StringProperty()
# [END parent_child_models]
112 changes: 112 additions & 0 deletions datastore/ndb/modeling/relation_model_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Copyright 2014 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.

"""Models for representing a contact with multiple titles and groups.
This module provides models with structured properties, strong
consistent querying, one-to-many grouping, many-to-many relationships.
Classes: Company, ContactCompany, Contact, Group, PhoneNumber
"""


from google.appengine.ext import ndb


# [START relation_model_models]
class PhoneNumber(ndb.Model):
"""A model representing a phone number."""
phone_type = ndb.StringProperty(
choices=('home', 'work', 'fax', 'mobile', 'other'))
number = ndb.StringProperty()


class Group(ndb.Model):
"""A model representing groups.
Expects to have a parent key with the id of the addressbook owner.
Example: assume my username is tmatsuo
addrbook_key = ndb.Key('AddressBook', 'tmatsuo')
friends = models.Group(parent=addrbook_key, name="friends")
friends.put()
"""
name = ndb.StringProperty()
description = ndb.TextProperty()

@property
def members(self):
"""Returns a query object with myself as an ancestor."""
return Contact.query(ancestor=self.key.parent()).filter(
Contact.groups == self.key)


class Contact(ndb.Model):
"""A model representing a contact entry.
Expects to have a parent key with the id of the addressbook owner.
Example: assume my username is tmatsuo
addrbook_key = ndb.Key('AddressBook', 'tmatsuo')
mary = models.Contact(parent=addrbook_key, name='Mary', ...)
mary.put()
"""
# Basic info.
name = ndb.StringProperty()
birth_day = ndb.DateProperty()

# Address info.
address = ndb.StringProperty()

phone_numbers = ndb.StructuredProperty(PhoneNumber, repeated=True)

# Group affiliation
groups = ndb.KeyProperty(Group, repeated=True)

# The original organization properties have been replaced by
# the following property.
@property
def companies(self):
rels = ContactCompany.query(ancestor=self.key.parent()).filter(
ContactCompany.contact == self.key)
keys = [rel.company for rel in rels]
return ndb.get_multi(keys)


class Company(ndb.Model):
"""A model representing a company."""
name = ndb.StringProperty()
description = ndb.TextProperty()
company_address = ndb.StringProperty()


class ContactCompany(ndb.Model):
"""A model representing a relation between a contact and a company.
Expects to have a parent key with the id of the addressbook owner.
Example: assume my username is tmatsuo
addrbook_key = ndb.Key('AddressBook', 'tmatsuo')
mary = models.Contact(parent=addrbook_key, name='Mary', ...)
mary.put()
models.ContactCompany(parent=addrbook_key, contact=mary.key,
company=google.key, title='engineer').put()
"""
contact = ndb.KeyProperty(Contact, required=True)
company = ndb.KeyProperty(Company, required=True)
title = ndb.StringProperty()
# [END relation_model_models]
Loading

0 comments on commit d0188c0

Please sign in to comment.