[Apologies if this gets delivered multiple times and hopefully I have 
formatted it correctly this time]

I am encountering multiple issues when trying to use PolyModels and bulkload
data. At a minimum, it appears the documentation is incomplete on how to
bulkload data for PolyModels. For instance, this issue

http://code.google.com/p/googleappengine/issues/detail?id=1133 

has been marked fixed, but I cannot find the documentation on the nature of 
the fix and the details on what the new 
constructs (model: instead of kind:) mean. There is only a reference to 
samples hosted on appspot.

Here is an example set of models, loaders and the issues I encounter:

class Record(db.Model):
 ...

class Parent(polymodel.PolyModel):
   ival = db.IntegerValue()

class Child(Parent):
  sval = db.StringValue(required=True)
  record = db.ReferenceProperty(Record, required=True)

bulkloader.yaml:
- model: models.Child
  name: Child
  connector: simplexml
  connector_options:
    xpath_to_nodes: /Children/Child
    style: element_centric
  property_map:
   - property: __key__                                                       
                                                                            
  
      external_name: key
      export_transform: transform.key_id_or_name_as_string
      import_transform: transform.create_foreign_key('Parent', True)
    - property: ival
      external_name: ival
      import_transform: transform.none_if_empty(long)
    - property: sval
      external_name: sval
 - property: record                                                         
                                                               
      external_name: record                                                 
                       
      import_transform: transform.create_foreign_key('Record', True)         
                                                                            
 
      export_transform: transform.key_id_or_name_as_string 

Here is my XML data file which I am trying to import into the datastore:

<Children>                                                              
<Child>
  <key>11</key>
  <ival>10</ival>
  <sval>someval</sval>
  <record>1</record>
</Child>
<Child>
  <key>2</key>
  <ival>20</ival>
  <sval>20val</sval>
  <record>2</record>
</Child>
<Child>
  <key>3</key>
  <ival>30</ival>
  <sval>30val</sval>
  <record>1</record>                                                         
                                                                           
</Child>
</Children>   

There are two issues that I hit. 

a) If the bulkloader.yaml specifies a property transform for __key__ then, 
no
instances are uploaded (and bulkloader says N records successfully 
transferred,
N being correct).    

b) If I implement workarounds for a) and proceed, then I hit the second
issue. The second issue is that if a property is marked with required=True, 
then
a BadValueError is thrown since the created model does not have any 
properties
set. 

Both issues center around DictConverter.__create_instance in
bulkloader_config.py.  

  def __create_instance(self, input_dict, bulkload_state):
    key = None
    if self._create_key:
      key = self.__dict_to_prop(self._create_key, input_dict, 
bulkload_state)

      if isinstance(key, (int, long)):
        key = datastore.Key.from_path(self._transformer_spec.kind, key)
      if isinstance(key, datastore.Key):
        parent = key.parent()
        if key.name() == None:
          return datastore.Entity(self._transformer_spec.kind,
                                  parent=parent, id=key.id())
        else:
          return datastore.Entity(self._transformer_spec.kind,
                                  parent=parent, name=key.name())
    if self._transformer_spec.model:
      return self._transformer_spec.model(key=key)
    return datastore.Entity(self._transformer_spec.kind, name=key)

For issue a), the code ends up creating an entity with
self._transformer_spec.kind (and the specified id) which causes problems 
later
in __run_import_transforms() which are unable to set attributes on the
instance. So the instance ends up being empty. 

The workaround I tried was to make the code so: 

 if self._create_key:                                                       
                                                                            
 
      key = self.__dict_to_prop(self._create_key, input_dict, 
bulkload_state)  
      if self._transformer_spec.model:
          return self._transformer_spec.model(key=key)

This works great until I hit issue b). It turns out that creating models 
through
their constructions causes BadValueErrors during validation of properties 
with
required=True. 

At this point, I am stuck. I really want to continue keeping the 
required=True
validators and also would like to use PolyModels for their conceptual
elegance. Can anyone suggest some ways of proceeding? 

thanks,
Vasanth

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en.

Reply via email to