开发者

Help in constructing a GQL query for a one to many relationship

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_an开发者_开发百科d_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_name is 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_city call, you will end in hitting the datastore too much to fetch the city_name and country_name properties when dereferenced.

What could you do? Denormalization and prefetching.

  1. Add a country_name property in the UserReportedCity model definition
  2. Prefetch ReferenceProperty to retrieve the UserReportedCity object for each UserReportedStatus object
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜