简体   繁体   中英

GAE DataStore referenceProperty relationship

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM