umongo icon indicating copy to clipboard operation
umongo copied to clipboard

EmbeddedField field not accept many argument

Open malinich opened this issue 6 years ago • 6 comments

AttributeError: 'list' object has no attribute 'items'

see the stacktrace below

i have this schema

@Application.db_instance.register
class Comment(EmbeddedDocument):

    user = fields.UUIDField(required=True)
    text = fields.StringField(validate=validate.Length(min=3), required=True)
    created = fields.DateTimeField(missing=datetime.datetime.now)



@Application.db_instance.register
class Blog(Document):
    title = fields.StringField(validate=validate.Length(max=128), required=True)
    text = fields.StringField(validate=validate.Length(min=128), required=True)
    user = fields.UUIDField(required=True)
    comments = fields.EmbeddedField(Comment, missing=[], many=True)

    class Meta:
        collection = Application.db.blog

my payload

{
    "title": "...some title .....",
    "text": "...some text... ",
    "user": "e365eb8d-b802-4f57-bc58-939a870fefb5",
    "comments": [
        {
        "user": "e365eb8d-b802-4f57-bc58-939a870fefb6",
        "text": "some comments"
        }
    ]
}

commit result

data = tornado.escape.json_decode(self.request.body)
blog = Blog(**data)
await blog.commit()

stracktrace

   File "/python3.6/site-packages/umongo/document.py", line 143, in __init__
    self._data = self.DataProxy(kwargs if kwargs else None)
  File "/python3.6/site-packages/umongo/data_proxy.py", line 22, in __init__
    self.load(data or {})
  File "/python3.6/site-packages/umongo/data_proxy.py", line 99, in load
    loaded_data, err = self.schema.load(data, partial=True)
    
 File "/python3.6/site-packages/marshmallow/schema.py", line 500, in load
    result, errors = self._do_load(data, many, partial=partial, postprocess=True)
  File "/python3.6/site-packages/marshmallow/schema.py", line 580, in _do_load
    index_errors=self.opts.index_errors,
  File "/python3.6/site-packages/marshmallow/marshalling.py", line 295, in deserialize
    index=(index if index_errors else None)
  File "/python3.6/site-packages/marshmallow/marshalling.py", line 68, in call_and_store
    value = getter_func(data)
  File "/python3.6/site-packages/marshmallow/marshalling.py", line 288, in <lambda>
    data
  File "/python3.6/site-packages/umongo/abstract.py", line 127, in deserialize
    return super().deserialize(value, attr=attr, data=data)

File "/python3.6/site-packages/marshmallow/fields.py", line 265, in deserialize
    output = self._deserialize(value, attr, data)
  File "/python3.6/site-packages/umongo/fields.py", line 437, in _deserialize
    return self._deserialize_from_mongo(data)
  File "/python3.6/site-packages/umongo/fields.py", line 447, in _deserialize_from_mongo
    return self.embedded_document_cls.build_from_mongo(value)
  File "/python3.6/site-packages/umongo/embedded_document.py", line 137, in build_from_mongo
    doc.from_mongo(data)
  File "/python3.6/site-packages/umongo/embedded_document.py", line 141, in from_mongo
    self._data.from_mongo(data)
  File "/python3.6/site-packages/umongo/data_proxy.py", line 66, in from_mongo
    for k, v in data.items():
AttributeError: 'list' object has no attribute 'items'
500 POST / (127.0.0.1) 49.79ms

operating system name and version: ubuntu 17.10; python 3.6 my libs:

marshmallow==3.0.0b4
motor==1.1
pymongo==3.5.1
python-dateutil==2.6.1
tornado==4.5.2
umongo==0.15.0

with marshmallow==2.15.0 it raises too

malinich avatar Dec 13 '17 14:12 malinich

comments = fields.EmbeddedField(Comment, missing=[], many=True)

Don't use many. Use a ListField(EmbeddedField).

Also (unrelated), don't pass a mutable to missing or it will be shared with all objects (Python pitfall, nothing to do with umongo/Marshmallow). Marshmallow/umongo allows you to pass a callable, so you can write missing=list.

Try this:

comments = fields.ListField(fields.EmbeddedField(Comment), missing=list)

lafrech avatar Dec 13 '17 15:12 lafrech

oh, i am so stupid person ) thank it help me

malinich avatar Dec 13 '17 15:12 malinich

Don't blame yourself. This was not obvious.

People used to working with Marshmallow are likely to face the same issue.

@touilleMan, should we add a warning in the code ? in the docs ?

lafrech avatar Dec 13 '17 15:12 lafrech

Sorry for delay

I'm ok for a warning in the documentation ;-)

touilleMan avatar Jan 12 '18 16:01 touilleMan

@malinich would you be willing to share how you managed to get await blog.commit() functional in tornado? Currently, my tornado blocks on await (I think because commit returns a generator). How did you solve this? Are you using the asyncio loop?

javdrher avatar Feb 14 '18 22:02 javdrher

blueprints - here https://gist.github.com/malinich/d729b78f79a8a8c706812e10ebd5e25a

malinich avatar Feb 15 '18 19:02 malinich