I am trying to get all parent/children from a one to many relationship. Traditionally, I could do this with a join, but doing so in the datastore is escaping me.
I have found several partial examples to do this, but not one that is complete yet.
I have:
class Owner(db.Model):
name = db.StringProperty()
class Pet(db.Model):
petname = db.StringProperty()
owner = db.ReferenceProperty(Owner, collection_name='pets')
#now I want to print all pets owned by scott
scott = Owner(name="scott")
scott.put()
Pet(owner=scott,petname="rufus").put()
pets = Pet.all().filter('owner =', "scott").fetch(100)
print Pet.all().filter('owner =', "scott").fetch(0)
Your query should work fine if you remove the quotes around "scott", I think.
You could also make all of Scott's Pet entities have his entity as their parent:
class Owner(db.Model):
name = db.StringProperty()
class Pet(db.Model):
petname = db.StringProperty()
scott = Owner(name="scott")
scott.put()
Pet(parent=scott, petname="rufus").put()
Pet(parent=scott, petname="fluffy").put()
Pet(parent=scott, petname="snoogums").put()
pets = Pet.all().ancestor(scott).fetch(100)
# Feed pets to your templating engine. So to speak.
By making scott the parent of the Pet entities, they are all added to the same entity group, and the ancestor
query gives you a simple and stragihtforward way to get all of the Pet
entities that are children of the given `Owner'. You should get much better performance with an ancestor query than a non-ancestor query.
This does impose the limitation that the Pet entities can only belong to one entity group, and if you wanted to have a Pet
involved in multiple data relationships, you would have to choose another approach. If it is a one-to-one relationship, just storing a Reference to the other related entity.
To have a printable representation of your Pet
entity, give it a __unicode__
method, something like this:
class Pet(db.Model):
petname = db.StringProperty()
def __unicode__(self):
return "I am " + self.petname
__unicode__
should return a string with the information that you want to see printed by the print
statement. As Nick wisely points out in comments, you should not use print
in an AppEngine application. The SDK comes with Django templates and Jinja2. Use one of those or import one that you prefer.
Look at The GQL examples made by google.
Use the owner name as unique key giving 'scott' to key_name instead of 'name' when instanciating Owner.
scott = Owner(key_name="scott")
Create the pet with scott as parent
pet = Pet(key_name='rufus', parent=scott)
And query his pets with
SELECT * FROM Pets WHERE ANCESTOR IS KEY('Owner', 'scott')
You should filter by Key of Owner:
#not str "scott", use scott object.
pets = Pet.all().filter('owner =', scott).fetch(100)