2

I have some troubles with the _data attribute of a mongoengine Documentinstance after upgrading from version 0.10.0 to 0.10.6

I define a class inheriting from Document

from mongoengine import *

__all__ = ('User',)

connect('mydb')

class User(Document):
    user_id = IntField(unique=True)
    username = StringField()

    meta = {'indexes': ['user_id','username'],
            'index_background' : True}

Until now, I used mongoengine version 0.10.0

To access the dict of data a Userinstance, I used to deal with the _dataattribute.

In [1]: User.objects.first()._data
Out[1]: 
{'id':ObjectId('55b6290a10976a2a0908f8a3'),
'user_id': 1,
'username': "fake_user"}

In [15]: type(User.objects.first()._data)
Out[15]: dict

Now, I upgraded the version of mongoengine to version 0.10.6

In [2]: User.objects.first()._data
Out[2]: 
{"id": 'id',
"user_id": 'user_id',
"username": 'username'} 

In [2]: type(User.objects.first()._data)
Out[2]: mongoengine.base.datastructures.SpecificStrictDict

So _dataattribute is no longer of type dictand my code breaks when I try to store a list of users in a pandas.DataFrame doing :

df = pandas.DataFrame([u._data for u in User.objects])

I can't find any explanation in mongoengine changelog doc here

Can somebody explain me what is this mongoengine.base.datastructures.SpecificStrictDict? and how it works ?

arthur
  • 2,319
  • 1
  • 17
  • 24
  • Have a look at [this](http://stackoverflow.com/questions/6930144/underscore-vs-double-underscore-with-variables-and-methods) answer. Essentially though, names prefixed with a single underscore are not meant to be used by other code, they are an implementation detail and their use may change and break your code (as you have seen). I'm afraid this doesn't help, but does shed some light on why this has happened. – SiHa Jun 02 '16 at 15:42

2 Answers2

0

You could use json.loads to transform your document into the dictionary:

import json

user = User.objects.first()
json.loads(user.to_json())

PS. You shouldn't rely on private properties in the first place

matino
  • 17,199
  • 8
  • 49
  • 58
0

The Document._data becomes mongoengine.base.datastructures.SpecificStrictDict, through its repr is as the way you posted, but you can still use it as a dict. some_document._data['id'] will get you a ObjectId object.

If you want an pure dict, you could convert it back to dict d = dict(some_document._data) The method also works if you previous versions of mongoengine.

socrates
  • 1,203
  • 11
  • 16