A] Problem Summary:
I have one to many data models in my project. I need help constructing a query to get the “many” side data object based on the key of the “one” side data object.
Please refer to “EDIT#1” for the code that has worked, but still inefficient.
B] Problem details:
1] I have “UserReportedCountry” (one) to “UserReportedCity” (many) , “UserReportedCity” (one) to “UserReportedStatus” (many) data model relationships.
2] The key for UserReportedCountry is a country_name , example — “unitedstates”.
The key for UserReportedCity is country_name:city_name, example “unitedstates:boston.
UserReportedStatus has no special key name.
3] I have the users country and city name in my python code and I want to retrieve all “UserReportedStatus” objects based on the city key name which is “county_name:city_name”
C] Code excerpts:
1] database models:
class UserReportedCountry(db.Model):
country_name = db.StringProperty( required=True,
choices=['Afghanistan','Aring land Islands']
)
class UserReportedCity(db.Model):
country = db.ReferenceProperty(UserReportedCountry, collection_name='cities')
city_name = db.StringProperty(required=True)
class UserReportedStatus(db.Model):
city = db.ReferenceProperty(UserReportedCity, collection_name='statuses')
status = db.BooleanProperty(required=True)
date_time = db.DateTimeProperty(auto_now_add=True)
2] query I have tried so far:
def get_data_for_users_country_and_city(self,users_country,users_city):
key_name_for_user_reported_city = users_country + ":" + users_city
return UserReportedStatus.all().filter('city.__key__=', key_name_for_user_reported_city ).fetch(limit=10)
D] Technologies being used
1] Python
2] Google App engine
3] Django
4] Django models.
[EDIT#1]
I have tried the following mechanism to query the status objects based on the given city and country. This has worked, but i believe this is an inefficient mechanism to perform the task.
def get_data_for_users_country_and_city(self,users_country,users_city):
key_name_for_user_reported_city = users_country + ":" + users_city
city_object = UserReportedCity.get_by_key_name( key_name_for_user_reported_city )
return UserReportedStatus.gql('WHERE city=:1', city_object)
Your last query looks correct and I don’t see any problem of inefficiency on it; in fact querying
by_key_nameis pretty fast and efficient.I think you have room of improvement on your normalized RDMBS oriented Models design instead; since GAE does not support JOINS, after the
get_data_for_users_country_and_citycall, you will end in hitting the datastore too much to fetch thecity_nameandcountry_nameproperties when dereferenced.What could you do? Denormalization and prefetching.
country_nameproperty in theUserReportedCitymodel definitionUserReportedCityobject for eachUserReportedStatusobject