问题描述:

I want to create a hierarchical database structure something like this:

State

City

address

where the ndb model looks like this

class address(ndb.model):

housenumber = ndb.stringProperty()

street = ndb.stringProperty()

in my code I create entities like this

itemkey = address()

itemkey.housenumber = '1003'

itemkey.street = 'foobar'

Now how do I create the hierarchy I want? the documentation does not show any examples. I am reasoning that if I have ancestors established (city and state), my queries will be much faster instead of having them in the ndb model class as indexed properties. Am I right?

网友答案:

You can use ancestors (in the key) or KeyProperties to create the hierarchy. Which you choose depends heavily on the way you will use data. If the tree/hierarchy is heavy on writes a single big entity group will limit your write throughput. A hierarchy made up from ancestors can't be changed, (ie you can't rekey things) so if you want to re-arange things you have to re-write everything. Using KeyProperties to point to parent(s) or repeated properties to point to children means only small updates to move entities around.

In your example an ancestor heirarchy would probably work as house numbers and streets don't change much. But if you added owners/people you would probably want to use KeyProperties instead as people move house etc......

Walking a tree using lists of KeyProperties as children is quick as you only need to use get() rather than queries. Of course this approach won't scale for large numbers of immediate children.

If each child has a KeyProperty holding it's immediate parent, then you can query for all immediate children, the downside is you can't query for all children regardless of depth with a single query.

A downside of ancestor queries to find children is you will get all children regardless of depth unless you store other details you can use to filter child depth.

As you can see all the potential approaches have their own strengths and weaknesses.

I would suggest you design a niave model and look at your use cases and data access/manipulation requirements to work out what specific approach you need to use.

I use heirarchies for a CMS, and don't use ancestors as I want to be able to move things (subtrees) around. In another project (Education Provider - Course - Unit heirarchy ) we use ancestors as this structure is fixed and each step down the heirarchy is a different type. So restricting the children in queries is easy.

In terms of your example if you wanted to use ancesors with city/state etc you would do something like:

class State(ndb.Model):
  pass

class City(ndb.Model):
  pass

class address(ndb.model):
  housenumber = ndb.stringProperty()
  street = ndb.stringProperty()

state = State(key_name="Western Australia")
state.put()

city = City(ancestor=state.key, key_name="Perth")
city.put()


itemkey = address(ancestor=city.key)
itemkey.housenumber = '1003'
itemkey.street = 'foobar'
相关阅读:
Top