heynemann / motorengine

Motorengine is a port of MongoEngine for Tornado.
http://motorengine.readthedocs.org
204 stars 67 forks source link

When attribute has underscore, pulling self._values returns a keyerror on 2nd hit. #123

Closed davidchua closed 6 years ago

davidchua commented 8 years ago

Version: 0.9.0

When attempting to output a Document's fields, if there is an attribute with an underscore (ie. _aasm_state), it will return an error on the 2nd time a self._values is called.

      File "/home/davidc/.virtualenvs/tgb_tornado/lib/python3.5/site-packages/motor/__init__.py", line 627, in _callback
        callback(result, None)
      File "/home/davidc/.virtualenvs/tgb_tornado/lib/python3.5/site-packages/motorengine/queryset.py", line 469, in handle
        obj = self.__klass__.from_son(doc)
      File "/home/davidc/.virtualenvs/tgb_tornado/lib/python3.5/site-packages/motorengine/document.py", line 60, in from_son
        field_values[field.name] = cls._fields[field.name].from_son(value)
    KeyError: 'aasm_state'

My Model:

class Trip(MongoDocument):
  # fields definition

  def output(self):
      return self._values

Example Object

    {
      "_aasm_state": "traveller_requested",
      "updated_at": "2016-07-24T10:44:30.275000",
      "created_at": "2016-07-24T00:51:44.103000",
    }

When I remove the attribute _aasm_state, calls made to trip.output() repeatedly returns no errors.

Also, if I were to add a debugger in

def output(self):
    import ipdb;ipdb.set_trace();
    return self._values

And make a single call, the debugger will hit the breakpoint twice instead of once.

davidchua commented 8 years ago

I've traced it down to

https://github.com/heynemann/motorengine/blob/76373643924def366756f0de0b886ede692658e1/motorengine/fields/dynamic_field.py#L14

What was the reason we stripped underscores in dynamic fields?

christ0pher commented 7 years ago

Hi,

when you look at: https://github.com/heynemann/motorengine/blob/76373643924def366756f0de0b886ede692658e1/motorengine/document.py#L29 and https://github.com/heynemann/motorengine/blob/76373643924def366756f0de0b886ede692658e1/motorengine/document.py#L59

You will see that all fields in the document are stored and accessed with the field name without . The name method therefore returns the name without . Only in the database itsself the dynamic field is stored with _ to identify them.

chris

thekie commented 6 years ago

@christ0pher's PR is now merged. It should work now as expected. Have a nice day!