limeuser / appengine-ndb-experiment

Automatically exported from code.google.com/p/appengine-ndb-experiment
Other
0 stars 0 forks source link

populate ndb.Model instance with Structured Properties from dict -- _from_dict() #207

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The populate() method updates a ndb.Model instance properties from a dict. It's 
great for updating data based on json params coming from client apps.

However, when you try to use the populate() method on a ndb.Model instance 
which has Structured Properties, it will fail: the populate() method does not 
automatically convert the value of dict which corresponds to the Structured 
Property. It will be expecting an instance of the Structured Property but it 
will receive a dict.

You can reproduce the problem trying to populate a instance of User in case 
below:

class Birthday(ndb.Model):
  day = ndb.IntegerProperty()
  month = ndb.IntegerProperty()
  year = ndb.IntegerProperty()

class User(ndb.Model):
  name = ndb.StringProperty()
  birthday = ndb.StructuredProperty(Birthday)
  # ... other properties

Additional discussion on: 
http://stackoverflow.com/questions/12367714/app-engine-python-populate-structure
d-property-with-json-gives-error/12378343

Original issue reported on code.google.com by marco.m....@gmail.com on 12 Sep 2012 at 10:50

GoogleCodeExporter commented 9 years ago
I just thought of a possible solution. In the _validate() method of the 
StructuredProperty class, we could accept a dict and convert it to an instance 
of the required class by calling _populate() recursively. (Actually, it should 
call _set_attributes(), which avoids copying the dict.)

Original comment by guido@google.com on 13 Sep 2012 at 12:23

GoogleCodeExporter commented 9 years ago
Issue 147 has been merged into this issue.

Original comment by guido@google.com on 27 Sep 2012 at 2:11

GoogleCodeExporter commented 9 years ago
This issue was closed by revision 6b3f88b663a8.

Original comment by guido@google.com on 27 Sep 2012 at 2:41

GoogleCodeExporter commented 9 years ago
That was quick. Thanks!

Original comment by marco.m....@gmail.com on 27 Sep 2012 at 2:49

GoogleCodeExporter commented 9 years ago
Do LocalStructuredProperties need the same fix?

Original comment by jessegoo...@gmail.com on 15 Oct 2012 at 3:12

GoogleCodeExporter commented 9 years ago
They do, and a later change did fix them.

Original comment by guido@google.com on 15 Oct 2012 at 3:31

GoogleCodeExporter commented 9 years ago
This is a related issue: populating an expando with nested data (the equivalent 
of a structured property I guess?) from another expando.  Population works but 
when the entity is saved it fails with the error: NotImplementedError: Property 
d1 does not support <type 'dict'> types.  The error is thrown from 
ndb/model.py, around line 2492, at the end of 
GenericProperty(Property)._db_set_value(self, v, p, value).

The error can be reproduced with this unit test:

    def test_expando_population_issue(self):
        # create expando with nested elements
        # create another expando
        # populate from one to the other
        # save the populated expando
        class S(ndb.Expando):
            pass
        class D(ndb.Expando):
            pass
        class E(ndb.Expando):
            pass
        d = D(d1 = E(d2 = 'd2test'))
        s = S(s1 = 's1test')
        s.populate(**d.to_dict())
        s.put()

If this comment is indeed unrelated to the thread then let me know and i'll 
move it.  Thanks for your help!

Original comment by jessegoo...@gmail.com on 15 Oct 2012 at 12:43

GoogleCodeExporter commented 9 years ago
It is related, but please open another issue because I will not be able to fix 
it in time for the next release.

Original comment by guido@google.com on 15 Oct 2012 at 2:17