Search code examples
pythongoogle-app-enginebulkloader

Google appengine, Cannot fetch data from child model


My bulkloader.yaml looks like this:

- import: models

transformers:
- model: models.Company
  connector: csv
  connector_options:
    encoding: utf_8
    columns: from_header
  property_map:
    - property: __key__
      external_name: companyid
      import_transform: int
      export_transform: transform.key_id_or_name_as_string

    - property: name
      external_name: name    

- model: models.Home
  connector: csv
  connector_options:
    encoding: utf_8
    columns: from_header
  property_map:
    - property: __key__
      external_name: listid
      import_transform: int
      export_transform: transform.key_id_or_name_as_string

    - property: companyid
      external_name: companyid
      import_transform: transform.create_foreign_key('Company')
      export_transform: transform.key_id_or_name_as_string    

    - property: address
      external_name: address    

- model: models.Bid
  connector: csv
  connector_options:
    encoding: utf_8
    columns: from_header
  property_map:
    - property: __key__
      external_name: listid
      import_transform: int    
      export_transform: transform.key_id_or_name_as_string

    - property: listid
      external_name: listid  
      import_transform: transform.create_foreign_key('Home',key_is_id=True)    
      export_transform: transform.key_id_or_name_as_string

    - property: bidtext
      external_name: bidtext    
      import_transform: db.Text

My models.py looks like this

from google.appengine.ext import db

# Models
class Company(db.Model):
    """Models a real estate company"""
    companyid = db.Key()
    name = db.StringProperty()

class Home(db.Model):
    """Models an apartment, house, villa etc and its selling details"""
    listid = db.Key()
    companyid = db.ReferenceProperty(Company, collection_name='company')
    address = db.StringProperty()

class Bid(db.Model):
    """Models bidding against a listid from Home model"""
    listid = db.ReferenceProperty(Home, collection_name='biddings')
    bidtext = db.TextProperty()

I have uploaded the data on my local dev server and i can view the data using http://localhost:9999/_ah/admin/datastore. So data is uploaded and exists. I see the foreign keys too.

I am not able to access child data based on parent object. It returns empty. Below pasted is what i have been executing in interactive console on local dev datastore:

from google.appengine.ext import db
from models import Home,Bid,Company

#can access parent data from child i.e. Home
bd = Bid.get_by_id(4242)
hhh =  Home.get_by_id(int(bd._listid.name()))
print hhh.state

#Again, can access parent data from child i.e. Company
h = Home.get_by_id(4242)
print h.address
c = Company.get_by_id(int(h._companyid.name()))
print c.website

#Cannot find any data here (biddings is a collection name defined in Bid model)
b = Bid.gql("WHERE listid = :1", h)
for x in h.biddings:
    print x.bidtext

Output:

London
Riverview 24,
http://www.houses.com/

Solution

  • Alright I found what i was doing wrong. In my bulkloader.yaml, i was referencing entities as models instead of kind.

    Once i used

    - kind: Home
    

    instead of

    - model: models.Home
    

    Also i used key_is_id=True at both the foreign key references to solve the problem of finding parent and child data.

    Now this is how i access my parent and child data

    from google.appengine.ext import db
    from models import Home,Bid,Company
    
    #get home object
    h = Home.get_by_id(4242)
    print h.address
    
    #get parent values
    print h.companyid.website
    
    #get child values
    b = Bid.gql("WHERE listid = :1", h.key())
    for xb in b:
        print xb.bidtext
    

    I hope this helps some noob like me cause i wasted a lot of time behind this. Thank you everyone who took time to respond to this thread.