views:

197

answers:

1

How does one go about structuring his db.Models effectively?

For instance, lets say I have a model for Countries, with properties like "name, northern_hemisphere(boolean), population, states (list of states), capital(boolean).

And another model called State or county or something with properties "name, population, cities(list of cities).

And another model called Cities, with properties "name, capital(boolean), distance_from_capital, population.

I just made that up so bare with me. Obviously I need the Cities to store data related to certain States, and thus States needs data related to the specific Country. In my States model I would have California, Colorado etc, and each of those has to have a specific list of Cities.

How does one structure his models so they are related somehow? I am very new to MVC so am struggling conceptually. Is it possible to use the class(parent) constructor?

+4  A: 

If you want to store relational data in the datastore of Google App Engine, this is a great article to start out with: Modeling Entity Relationships.

You use ReferenceProperty to specify a relationship between two models:

class Country(db.Model):
    name = db.StringProperty(required=True)

class State(db.Model):
    country = db.ReferenceProperty(Country, collection_name='states')
    name = db.StringProperty(required=True)

class City(db.Model):
    state = db.ReferenceProperty(State, collection_name='cities')
    name = db.StringProperty(required=True)

Instances of your Country model will automatically get a new property called states which will be a query to get all related State entities. Same thing with the State model for cities. Its automatically created cities property will be a query to get all related City entities.

How to use:

# Create a new country:
us = Country(name='USA')
us.put()

# Create a new state
ca = State(name='California', country=us)
ca.put()

# Create a new city
la = City(name='Los Angeles', state=ca)
la.put()

# And another
sf = City(name='San Francisco', state=ca)
sf.put()

# Print states
for state in us.states:
    print state.name

    # Print cities
    for city in state.cities:
        print ' ' + city.name

Should output:

California
 Los Angeles
 San Francisco
Blixt
Thanks for the swift reply. Could you please elaborate slightly though. I mean relationally - I don't want them to inherit properties atm.
Dominic Bou-Samra
Ah, sorry, I changed my answer.
Blixt
Cool, that looks to be what I need - I'll look into it. I'll leave this question unanswered for the moment.
Dominic Bou-Samra
I updated my answer to be more relevant to your question.
Blixt
Ahhh, I see. So if I was to use something like "State.cities.population" it would return the population for that specific entity?
Dominic Bou-Samra
No, first of all, the property only exists on a model instance. So you would have to get a `State` instance first. On that instance you could access the cities like this: `for city in state.cities: print city.population`
Blixt
I updated my answer again.
Blixt
You are fantastic. Thanks for baring with me :P
Dominic Bou-Samra
One piece of advice: If you're actually strong country/state/city, you're probably better storing those in a data file and loading them into each instance directly - there's no need to store such a small, static amount of data in the datastore, and storing it in local memory will speed things up.
Nick Johnson
Nah I was just using that as an example to illustrate the connection. An yeah I will be using memcache.
Dominic Bou-Samra